Django学习笔记002之resetfull应用

学习目标:

  • 学习resetfull接口
  • 掌握Django web基础设施

学习内容:

1.学习resetfull接口

简介

人工智能解释:
resetfull简介

应用场景

以下是人工智能使用Django框架实现的restfull接口代码:

#views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import UserModel
import json
 @csrf_exempt
def user_list(request):
    # GET方法,获取用户列表
    if request.method == 'GET':
        users = UserModel.objects.all()
        data = []
        for user in users:
            data.append({'id': user.id, 'name': user.name, 'age': user.age})
        return JsonResponse(data, safe=False)
     # POST方法,创建新用户
    elif request.method == 'POST':
        # 从请求中获取 JSON 数据,并解析
        data = json.loads(request.body.decode('utf-8'))
        name = data['name']
        age = data['age']
        # 创建新用户并保存到数据库
        user = UserModel(name=name, age=age)
        user.save()
        # 返回创建的用户信息
        return JsonResponse({'id': user.id, 'name': user.name, 'age': user.age})
 @csrf_exempt
def user_detail(request, user_id):
    # 获取指定 ID 的用户
    try:
        user = UserModel.objects.get(id=user_id)
    except UserModel.DoesNotExist:
        return JsonResponse({'error': 'User does not exist'}, status=404)
     # GET 方法,获取指定 ID 的用户信息
    if request.method == 'GET':
        data = {'id': user.id, 'name': user.name, 'age': user.age}
        return JsonResponse(data)
     # PUT 方法,更新指定 ID 的用户信息
    elif request.method == 'PUT':
        # 从请求中获取 JSON 数据,并解析
        data = json.loads(request.body.decode('utf-8'))
        user.name = data['name']
        user.age = data['age']
        # 更新用户信息并保存到数据库
        user.save()
        # 返回更新后的用户信息
        data = {'id': user.id, 'name': user.name, 'age': user.age}
        return JsonResponse(data)
     # DELETE 方法,删除指定 ID 的用户信息
    elif request.method == 'DELETE':
        user.delete()
        return JsonResponse({'message': 'User deleted'})

在这个示例中,我们使用Python的Django框架实现了一个简单的RESTful API,包括获取所有用户、获取指定用户、创建用户、更新用户和删除用户等操作。我们通过HTTP协议中的GET、POST、PUT和DELETE方法来对用户资源进行不同的操作,并返回不同的响应状态码和数据格式。使用这个API,我们可以通过浏览器、命令行工具或其他HTTP客户端发送请求,并与服务端进行通信,实现数据的增删改查等操作。

学习点记录:
Q:from django.views.decorators.csrf import csrf_exempt 这句代码意思是?
A: 这句代码的作用是使视图函数免除跨站请求伪造(CSRF)保护。
在Django中,默认情况下,所有的POSTPUTDELETE等需要修改数据的请求都需要附带CSRF令牌,以防止跨站请求伪造的攻击。如果没有加上csrf_exempt装饰器,则视图函数会检查请求中是否包含有效的CSRF令牌,如果没有,则会返回403 Forbidden
而使用csrf_exempt装饰器可以告诉视图函数忽略CSRF令牌的检查,从而使得我们能够方便地对API进行测试和调试。但是,注意要确保在真正的生产环境中,所有的POST、PUT、DELETE请求都要附带有效的CSRF令牌,以保障网站的安全性
Q:from .models import UserModel 这句函数什么意思?
A: 这句代码的含义是从当前目录下的 models 模块中导入 UserModel 模型。其中 . 表示当前目录,而 models 是Python模块的文件名, .py 扩展名可省略。
在Django中,模型是与数据库表相对应的数据模型。 UserModel 模型是程序中定义的一个简单模型,包含了用户的姓名和年龄两个字段。在实际的应用中,我们可以根据需要定义更加复杂的模型,例如文章、评论、订单等等。
使用模型的好处是可以方便地通过代码来操作数据库,不需要手写SQL语句。当我们在程序中定义好了模型后,就可以通过Django的ORM框架来实现数据的增删改查等操作。ORM框架会自动将我们的操作转化为对数据库的增删改查操作,并且在必要的时候还会自动处理事务、校验数据等问题,使得我们能够更加方便、安全、高效地操作数据库。

实验途径

使用如下方法,我们可以向一个URL发送不同的resetfull请求:

# 发起GET请求
import requests
 response = requests.get('http://example.com')
print(response.content)

# 发起POST请求
import requests
 url = 'http://example.com/api/create'
data = {'name': 'John', 'age': 30}
 response = requests.post(url, data=data)
print(response.content)

# 发起PUT请求
import requests
 url = 'http://example.com/api/update'
data = {'name': 'John', 'age': 31}
 response = requests.put(url, data=data)
print(response.content)

# 发起DELETE请求
import requests
 url = 'http://example.com/api/delete'
data = {'id': 123}
 response = requests.delete(url, data=data)
print(response.content)

2.Django web基础设施

简介

Django提供了很多与浏览器通信的机制,例如url路由使用模板定制化htmlresetfull接口实现等。

应用目录结构

目录结构如下图:
treestruct

demo001\1.asgi.py

此文件用来处理异步请求。ASGI 是一种异步Web服务器网关接口,用于处理异步请求。它是一种全新的接口定义,使用异步I/O来提高性能和伸缩性(以至于服务器忙于等待某个IO到来而阻塞了其他服务,这样会导致cpu时间片的白白浪费),并且可以处理多种数据交换协议,通常使用单线程的事件循环实现,也可以使用多进程或集群进行水平扩展。

demo001\2.wsgi.py

Django 早期的 Web 服务器是基于 WSGI 的服务器。

demo001\3.settings.py

该文件为项目配置文件,在django启动时,会从该文件中获取配置信息,比如安装app。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'daphne',
    #'django.contrib.staticfiles',
]
demo001\4.urls.py

此文件用于注册url和视图函数。

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/', include('myapp.urls')),
]

常用技巧手段

1.使用asgi作为web服务器

1.创建 ASGI 应用程序
在你的 Django 项目目录下,创建一个名为 asgi.py 的文件,输入以下内容:

import os
from django.core.asgi import get_asgi_application
 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
application = get_asgi_application()

注意将 myproject 替换为你的项目名称
2.下载 ASGI 服务器
为了部署 ASGI 应用程序,需要先安装一个 ASGI 服务器。这里我们选择使用 Daphne 作为 ASGI 服务器,可以通过以下命令进行安装:

pip install daphne

3.部署 ASGI 应用程序
接下来,使用 Daphne 服务器部署 ASGI 应用程序。有两种部署方式,命令行部署如下:

daphne myproject.asgi:application

源码部署方式如下:

修改settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'daphne',
    #'django.contrib.staticfiles',
]
ASGI_APPLICATION = 'myproject.asgi.application'

这将启动一个 Daphne 服务器实例,使用 myproject 应用程序的 ASGI 配置。

2.使用wsgi作为web服务器

作为早期的服务器,不需要适配,Django默认支持。默认配置如下:

# wsgi.py
import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'demo001.settings')

application = get_wsgi_application()
# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
# 下面配置无所谓,代码中有动态适配
# 代码app_path = getattr(settings, "WSGI_APPLICATION")
WSGI_APPLICATION = 'demo001.wsgi.application'
3.使用GET接口接收客户端请求

get为获取数据。请求url一般使用的是get命令。
使用form表单提交get请求:

视图函数

@csrf_exempt
def my_test(request):
    if request.method == 'GET':
        print("This is a GET request!!")
        print("request.GET %s" %request.GET)
    elif request.method == 'POST':
        print("This is a POST request!!")
        print("request.POST %s" %request.POST)
    else:
        pass

    global count
    count += 3
    print("my_test count:%s" %count)
    return render(request, 'test.html')

url路由

app_name = 'myapp'

urlpatterns = [
    path('test', my_test)
]

html form表单

<!DOCTYPE html>
<html>
<head>
</head>

<body>
    <form method="get">
        <input type="text" name="hs5name">
        <input type="number" name="h5age">
        <button type="submit">Submit</button>
    </form> 
</body>
</html>

点击Submit向后台请求GET命令。

4.使用POST接口接收客户端请求

post为提交数据。
使用form表单提交post请求:

html form表单

<!DOCTYPE html>
<html>
<head>
</head>

<body>
    <form method="post">
        <input type="text" name="hs5name">
        <input type="number" name="h5age">
        <button type="submit">Submit</button>
    </form> 
</body>
</html>

点击Submit向后台请求POST命令。其他代码与GET命令一致。

5.使用PUT接口接收客户端请求

由于安全原因,Web 应用程序有时会禁用 PUT 和 DELETE 方法。

6.使用DELETE接口接收客户端请求

由于安全原因,Web 应用程序可能会禁用 PUT 和 DELETE 方法。

7.创建视图函数和url路由表

视图函数一般分为函数视图、类视图、通用视图

7.1. 函数视图

urls.py

urlpatterns = [
    path('hello', hello),
]

views.py

def hello(request):
    return HttpResponse("Hello, Django!")
7.2. 类视图

一种继承自 View 类的自定义实现的视图类。

views.py

from django.views import View
from django.http import HttpResponse

class HelloView(View):
    def get(self, request):
        return HttpResponse("Hello, Django!")

urls.py

urlpatterns = [
    path('helloview', HelloView.as_view())
]
7.3. 通用视图

提供了一些常用的类试图工具。
1.TemplateView类

urls.py

from django.urls import path
from django.views.generic.base import TemplateView

urlpatterns = [
    path('about/', TemplateView.as_view(template_name='about.html'), name='about')
]

views.py

from django.urls import path
from django.views.generic.base import TemplateView

urlpatterns = [
    path('about/', TemplateView.as_view(template_name='about.html'), name='about')
]

templates/about.html

<!-- templates/about.html -->

<!DOCTYPE html>
<html>
    <head>
        <title>About Us</title>
    </head>
    <body>
        <h1>About Us</h1>
        <p>We are a company that does amazing things.</p>
    </body>
</html>

2.RedirectView类

urls.py

from django.urls import path
from django.views.generic.base import RedirectView

urlpatterns = [
    path('home/', RedirectView.as_view(url='http://www.baidu.com'), name='home')
]

3.ArchiveIndexView类
每次查询数据库所有的目标,最终按日志进行排序归类,并返回给前端。

models.py

class Article(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField()

    def __str__(self):
        return self.title
    
    class Meta:
        app_label = 'myapp'

urls.py

path('archiveindex/', BlogArchiveIndexView.as_view(), name='archiveindex'),

views.py

class BlogArchiveIndexView(ArchiveIndexView):
    date_field = 'pub_date'
    template_name = 'archiveindex.html'
    queryset = Article.objects.all()
    
    def get(self, request, *args, **kwargs):
        self.date_list, self.object_list, extra_context = self.get_dated_items()
        context = self.get_context_data(
            object_list=self.object_list, date_list=self.date_list, **extra_context
        )

        
        Article.objects.create(title=generate_random_chinese(5), pub_date='2023-05-20')
        Article.objects.create(title=generate_random_chinese(5), pub_date='2023-05-21')
        Article.objects.create(title=generate_random_chinese(5), pub_date='2023-05-22')

        class_list = []
        for date in self.date_list:
            article_list = []
            for article in self.object_list:
                if date.year == article.pub_date.year:
                    article_list.append(article)
            class_list.append([date, article_list])
        
        context.setdefault("class_list", class_list)
        return self.render_to_response(context)

archiveindex.html

<!DOCTYPE html>
<html>
  <head>
    <title>Blog Archive</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.0.0/css/bootstrap.min.css">
  </head>
  <body>
    <div class="container">
      <h1 class="mt-4 mb-3">Blog Archive</h1>

      {% for date, articles in class_list %}
        <div class="card mb-4">
          <div class="card-header">
            {{ date|date:"F Y" }}
          </div>
          <ul class="list-group list-group-flush">
            {% for article in articles %}
              <li class="list-group-item">
                <a href="{{ article.get_absolute_url }}">{{ article.title }}</a>
                <a href="{{ article.get_absolute_url }}">{{ article.pub_date }}</a>
              </li>
            {% endfor %}
          </ul>
        </div>
      {% endfor %}

    </div>
  </body>
</html>

4.YearArchiveView类
每次查询数据库指定年份的目标,将查询结果返回给前端。

models.py

class Event(models.Model):
    title = models.CharField(max_length=200)
    start_date = models.DateField()

    def __str__(self):
        return self.title
    class Meta:
        app_label = 'myapp'

urls.py

path('events/<int:year>/', EventYearArchiveView.as_view(), name="event_year_archive"),

views.py

class EventYearArchiveView(YearArchiveView):
    def __init__(self, *args, **kwargs):
        Event.objects.create(title='Test 1', start_date='2023-04-01')
        Event.objects.create(title='Test 2', start_date='2023-06-01')
        Event.objects.create(title='Test 3', start_date='2023-08-01')
        super().__init__(**kwargs)
    queryset = Event.objects.all()
    date_field = 'start_date'
    make_object_list = True
    allow_future = False
    allow_empty = True
    template_name = 'event_archive_year.html'

base.html & event_archive_year.html

<html>
<head>
    <title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
    <header>
        {% block header %}
            <h1>Default Header</h1>
        {% endblock %}
    </header>
    <div>
        {% block content %}
            <p>Default Content</p>
        {% endblock %}
    </div>
    <footer>
        {% block footer %}
            <p>Default Footer</p>
        {% endblock %}
    </footer>
</body>
</html>
{% extends "base.html" %}

{% block content %}
  <h2>Events in {{ year }}</h2>
  {% if object_list|length %}
    <ul>
    {% for event in object_list %}
      <li>{{ event.title }}-{{ event.start_date }}</li>
    {% endfor %}
    {% for date in date_list %}
        <li> {{date}} </li>
    {% endfor %}
    </ul>
  {% else %}
    <p>No events found.</p>
  {% endif %}
{% endblock content %}

输入url:http://127.0.0.1:8000/myapp/events/2023/ 既可以查看2023年的数据。
5.MonthArchiveView类
每次查询数据库指定月份的目标,将查询结果返回给前端。

models.py

class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_date = models.DateTimeField(auto_now_add=True)
    is_published = models.BooleanField(default=False)

urls.py

path('monthblog/<int:year>/<str:month>', BlogMonthArchiveView.as_view(), name='archive_month'),

views.py

class BlogMonthArchiveView(MonthArchiveView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        BlogPost.objects.create(title=generate_random_chinese(5), content=generate_random_chinese(20))
        BlogPost.objects.create(title=generate_random_chinese(5), content=generate_random_chinese(20))
        BlogPost.objects.create(title=generate_random_chinese(5), content=generate_random_chinese(20))

    model = BlogPost
    date_field = 'created_date'
    allow_future = False
    template_name = 'archive_month.html'
    paginate_by = 10

archive_month.html

{% extends "base.html" %}

{% block content %}
  <h2>Blogs in {{ months }}</h2>
  {% if object_list|length %}
    <ul>
    {% for Blog in object_list %}
      <li>{{ Blog.title }}-{{Blog.content}} {{ Blog.created_date }}</li>
    {% endfor %}
    {% for date in date_list %}
        <li> {{date}} </li>
    {% endfor %}
    </ul>
  {% else %}
    <p>No events found.</p>
  {% endif %}
{% endblock content %}

url: http://127.0.0.1:8000/myapp/monthblog/2023/May
6.WeekArchiveView类
每次查询数据库指定周的目标,将查询结果返回给前端。

models.py

class WeekReport(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_date = models.DateTimeField(auto_now_add=True)

views.py

class WeekReportArchiveView(WeekArchiveView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        WeekReport.objects.create(title=generate_random_chinese(4), content=generate_random_chinese(20))
    
    model = WeekReport
    date_field = 'created_date'
    template_name = 'archive_week.html'

urls.py

path('weekreport', WeekReportArchiveView.as_view()),

html

{% extends "base.html" %}

{% block content %}
  <h2>Blogs in {{ week }}</h2>
  {% if object_list|length %}
    <ul>
    {% for Blog in object_list %}
      <li>{{ Blog.title }}-{{Blog.content}} {{ Blog.created_date }}</li>
    {% endfor %}
    {% for date in date_list %}
        <li> {{date}} </li>
    {% endfor %}
    </ul>
  {% else %}
    <p>No events found.</p>
  {% endif %}
{% endblock content %}

url: http://127.0.0.1:8000/myapp/weekreport?year=2023&week=21
7.DayArchiveView类
每次查询数据库指定天的目标,将查询结果返回给前端。

models.py

class DayModel(models.Model):
    my_title = models.CharField(max_length=255, verbose_name='标题')
    my_content = models.TextField(verbose_name='内容')
    my_date_field = models.DateTimeField(verbose_name='日期', auto_now_add=True)

    class Meta:
        verbose_name = '我的模型'
        verbose_name_plural = '我的模型'

    def __str__(self):
        return self.my_title

views.py

class MyDayArchiveView(DayArchiveView):
    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        DayModel.objects.create(my_title=generate_random_chinese(4), my_content=generate_random_chinese(20))
    queryset = DayModel.objects.all()
    date_field = "my_date_field"
    template_name = 'archive_day.html'
    allow_future = True

urls.py

path('dayarchive/<int:year>/<str:month>/<int:day>', MyDayArchiveView.as_view()),

archive_day.html

{% extends "base.html" %}

{% block content %}
  <h2>daily in {{ day }}</h2>
  {% if object_list|length %}
    <ul>
      <li>标题-内容-创建时间</li>
    {% for daily in object_list %}
      <li>{{ daily.my_title }}-{{daily.my_content}}: {{ daily.my_date_field }}</li>
    {% endfor %}
    {% for date in date_list %}
        <li> {{date}} </li>
    {% endfor %}
    </ul>
  {% else %}
    <p>No events found.</p>
  {% endif %}
{% endblock content %}

url:http://127.0.0.1:8000/myapp/dayarchive/2023/MAY/27
8.TodayArchiveView类
每次查询数据库当天的目标,将查询结果返回给前端。

models.py

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    pub_date = models.DateTimeField(auto_now_add=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

urls.py

    path('today/', TodayPostArchiveView.as_view()),
    path('post/<int:pk>/', post_detail, name='post_detail'),

views.py

class TodayPostArchiveView(TodayArchiveView):
    queryset = Post.objects.all()
    date_field = "pub_date"
    template_name = "post_archive.html"
    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        try:
            user = User.objects.get(username='jack')
            if user:
                print("user exist!!!")
        except User.DoesNotExist:
            user = User.objects.create(username='jack')

        post = Post.objects.create(
            title='my post',
            content='hello, world!',
            author=user
        )

def post_detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'post_detail.html', {'post': post})

post_archive.html

{% extends "base.html" %}

{% block content %}
  <h1>Archive for {{ day }}</h1>
  <ul>
    {% for post in object_list %}
      <li>
        <a href="{% url 'myapp:post_detail' post.pk %}">{{ post.title }}</a>
        <br>
        <small>Published on {{ post.pub_date }} by {{ post.author }}</small>
      </li>
    {% empty %}
      <li>No posts yet.</li>
    {% endfor %}
  </ul>
{% endblock %}

post_detail.html

{% extends 'base.html' %}

{% block content %}
  <h1>{{ post.title }}</h1>
  <p>{{ post.pub_date|date }}</p>
  <div>{{ post.content }}</div>
{% endblock %}

url:http://127.0.0.1:8000/myapp/today/
9.DateDetailView类
每次查询数据库指定天中某个目标(这个目标是唯一的,比如主键),将查询结果返回给前端。

models.py

class DetaiModel(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.title

views.py

class MyModelDetailView(DateDetailView):
    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        DetaiModel.objects.create(title=generate_random_chinese(3), content=generate_random_chinese(200))
    model = DetaiModel
    date_field = "updated_at"
    month_format = "%m"
    day_format = "%d"
    slug_field = "slug"
    context_object_name = "mymodel"
    template_name = "mymodel_detail.html"

urls.py

    path('datedetail/<int:pk>/', MyModelDetailView.as_view()),

mymodel_detail.html

{% extends "base.html" %}

{% block content %}
  <article class="my-model-detail">
    <h1>{{ mymodel.title }}</h1>
    <div class="created-at">创建于:{{ mymodel.created_at }}</div>
    <div class="created-at">更新于:{{ mymodel.updated_at }}</div>
    <div class="content">{{ mymodel.content }}</div>
  </article>
{% endblock %}

url:http://127.0.0.1:8000/myapp/datedetail/20/?year=2023&month=05&day=27
10.DetailView类
每次查询数据库指定某个目标(这个目标是唯一的,比如主键),将查询结果返回给前端。

models.py

class MyDetaiModel(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

views.py

class MyDetailView(DetailView):
    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        MyDetaiModel.objects.create(name=generate_random_chinese(3), description=generate_random_chinese(200))
    template_name = 'my_detailview.html'
    model = MyDetaiModel
    context_object_name = 'my_detailview'
    pk_url_kwarg = 'my_id'

urls.py

    path('my_model_detail/<int:my_id>/', MyDetailView.as_view(), name='my_model_detail'),

my_detailview.html

{% block content %}
<h1>{{ my_detailview.name }}</h1>
<p>描述:{{ my_detailview.description }}</p>
<p>创建时间:{{ my_detailview.created_at }}</p>
{% endblock %}

url:http://127.0.0.1:8000/myapp/my_model_detail/16/
11.FormView类
处理表单的视图函数,将Web前端提交数据的结果返回给Web前端。

views.py

class ContactForm(forms.Form):
    name = forms.CharField()
    email = forms.EmailField()
    message = forms.CharField(widget=forms.Textarea)

class ContactView(FormView):
    template_name = 'contact.html'
    form_class = ContactForm
    success_url = reverse_lazy('myapp:success')

    def form_valid(self, form):
        # 处理提交的表单数据
        name = form.cleaned_data['name']
        email = form.cleaned_data['email']
        message = form.cleaned_data['message']
        # ... 这里可以将数据保存到数据库等等操作
        return super().form_valid(form)

def success_view(request):
    return render(request, 'success.html')

urls.py

    path('formview/', ContactView.as_view(), name='contact'),
    path('success/', success_view, name='success'),

contact.html

{% extends "base.html" %}

{% block content %}
  {% if form.errors %}
    <p>Please correct the following errors:</p>
    <ul>
      {% for field in form %}
        {% for error in field.errors %}
          <li>{{ error }}</li>
        {% endfor %}
      {% endfor %}
    </ul>
  {% endif %}

  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Submit</button>
  </form>
{% endblock %}

success.html

{% extends "base.html" %}

{% block content %}
  <h1>Thank you for contacting us!</h1>
{% endblock %}

url:http://127.0.0.1:8000/myapp/success/
12.CreateView类
处理表单的视图函数,将Web前端提交数据保存到数据库,并使用post命令查询当前数据库数据返回给Web前端。

models.py

class MyFormModel(models.Model):
    name = models.CharField(max_length=50)
    content = models.TextField()

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyFormModel
        fields = ['name', 'content']

views.py

class MyModelCreateView(CreateView):
    model = MyFormModel
    form_class = MyModelForm
    template_name = 'mymodel_create.html'
    success_url = reverse_lazy('myapp:mymodel_list')

class MyModelListView(ListView):
    model = MyFormModel
    template_name = 'mymodel_list.html'
    context_object_name = 'mymodels'

urls.py

    path('create/', MyModelCreateView.as_view(), name='mymodel_create'),
    path('mymodel_list/', MyModelListView.as_view(), name='mymodel_list'),

mymodel_create.html

{% extends 'base.html' %}

{% block content %}
  <h1>Create a new MyModel</h1>
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Create</button>
  </form>
{% endblock %}

mymodel_list.html

{% extends 'base.html' %}

{% block content %}
  <h1>My Models</h1>
  <ul>
  {% for mymodel in mymodels %}
    <li>{{ mymodel.name }}</li>
  {% empty %}
    <p>No models found.</p>
  {% endfor %}
  </ul>
{% endblock %}

url:http://127.0.0.1:8000/myapp/create/
13.UpdateView类
处理表单的视图函数,查询数据库数据并更新数据到数据库,然后查询当前数据库数据返回给Web前端。

views.py

class MyModelUpdateView(UpdateView):
    model = MyFormModel
    form_class = MyModelForm
    template_name = 'mymodel_update.html'
    success_url = reverse_lazy('myapp:mymodel_list')

urls.py

    path('update/<int:pk>/', MyModelUpdateView.as_view(), name='mymodel_update'),

mymodel_update.html

{% extends 'base.html' %}

{% block content %}
  <h1>Edit My Model</h1>
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Update</button>
  </form>
{% endblock %}

url:http://127.0.0.1:8000/myapp/update/5/
14.DeleteView类
通过url删除数据库指定数据,然后查询当前数据库数据返回给Web前端。

views.py

class MyModelDeleteView(DeleteView):
    model = MyFormModel
    template_name = 'mymodel_delete.html'
    success_url = reverse_lazy('myapp:mymodel_list')

urls.py

    path('delete/<int:pk>/', MyModelDeleteView.as_view(), name='mymodel_delete')

mymodel_delete.html

{% extends 'base.html' %}

{% block content %}
  <h1>Delete My Model</h1>
  <p>Are you sure you want to delete "{{ object }}"?</p>
  <form method="post">
    {% csrf_token %}
    <button type="submit">Delete</button>
    <a href="{% url 'myapp:mymodel_list' %}">Cancel</a>
  </form>
{% endblock %}

url:http://127.0.0.1:8000/myapp/delete/1/
15.ListView类
数据库所有数据,然后查询结果给Web前端。

views.py

class MyModelListView(ListView):
    model = MyFormModel
    template_name = 'mymodel_list.html'
    context_object_name = 'mymodels'

urls.py

    path('mymodel_list/', MyModelListView.as_view(), name='mymodel_list')

mymodel_list.html

{% extends 'base.html' %}

{% block content %}
  <h1>My Models</h1>
  <table>
    <thead>
      <tr>
        <th>主键</th>
        <th>名字</th>
        <th>内容</th>
      </tr>
    </thead>
    <tbody>
      {% for mymodel in mymodels %}
        <tr>
          <td>{{ mymodel.pk }}</td>
          <td>{{ mymodel.name }}</td>
          <td>{{ mymodel.content }}</td>
        </tr>
      {% empty %}
        <tr><td>NA</td><td>NA</td><td>NA</td></tr>
      {% endfor %}
  
    </tbody>
  </table>
{% endblock %}

16.GenericViewError类
当视图函数出现异常时,可以给增加异常处理中间件将错误输出到Web前端。

middleware.py

class MyExceptionMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):
        if isinstance(exception, GenericViewError):
            error_message = exception.message
            return HttpResponse(error_message, status=500)

views.py

class MyGenericViewError(GenericViewError):
    def __init__(self, message):
        self.message = message

def testGenericViewError(request):
    try:
        indx = list(5)
        indx[5] = 'xxxx'
    except Exception as ext:
        print(str(ext))
        raise MyGenericViewError("请求HTTP时出现错误:" + "testGenericViewError" + str(ext))

urls.py

    path('testViewError/', testGenericViewError),

url:http://127.0.0.1:8000/myapp/testViewError/

8.在html中使用Django模板函数
1.传递变量

使用render函数传递字典变量给模板。格式:{{var}}

urls.py

    path('testVariable/', testVariable),

views.py

def testVariable(request):
    context = {'variable': 12}
    return render(request, 'testVariable.html', context)

testVariable.html

{% extends "base.html" %}

{% block content %}
<h1> 接收到的数据值为:{{ variable }} </h1>
{% endblock %}

url:http://127.0.0.1:8000/myapp/testVariable/

2. 过滤器

Django4.2过滤器
将传递给模板的变量,按照过滤器指定的格式输出。格式:{{var|过滤器}}

testVariable.html

{% extends "base.html" %}

{% block content %}
<h1> 接收到的数据值为:{{ variable|add:"3" }} </h1>
{% endblock %}
3. 标签

常见的标签有if、for等,如Django4.2标签

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值