• [django框架2]ORM进阶知识


    经过上周的django学习与项目实战,想必对其也有了足够的了解。
    django基础知识
    项目实战

    本次django进阶知识重要围绕数据库管理操作为主,同时讲述了部分关于组件中间件的内容,希望有所帮助。

    其实在经过学习django后,学习java servlet ,springboot/cloud等会比较快的,接下来同样巩固django,学习之余以java为主要向导,层层深入!

    admin管理工具

    一般来说,admin是管理数据库信息。

    使用管理工具

    django提供了基于web的管理工具,django.contrib是其中一部分,可以在Installed_apps看见。
    通常在urls.py中自动设置好了
    /helloworld/views.py

    	url(r'^admin/',admin.site.urls),
    
    • 1

    然后在访问localhost:8000/admin/即可。
    提醒,前面的数据库建表要使用命令建表,否则会出现异常情况。
    可以通过命令

    $ python manage.py createsuperuser
    username:
    email:
    password:
    ...
    superuser created successfully
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    为了让admin管理某个数据模型,需要注册该数据模型到admin.(以Test为例)

    # /TestModel/admin.py
    from django.contrib import admin
    
    from TestModel.models import  Test
    # Register your models here.
    
    admin.site.register(Test)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    复杂模型

    管理页面功能强大,完全有能力处理更加复杂的数据模型。
    现在TestModel/models.py增加一个更加复杂的数据模型:

    class Contact(models.Model):
        name = models.CharField(max_length=200)
        age = models.IntegerField(default=0)
        email = models.EmailField()
        def __unicode__(self):
            return self.name
    
    class Tag(models.Model):
        contact = models.ForeignKey(Contact,on_delete=models.CASCADE,)
        name = models.CharField(max_length=50)
        def __unicode__(self):
            return self.name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里多了2个表,Tag以Contact为外键,在admin.py注册多个模型

    admin.site.register([Test,Contact,Tag])
    
    • 1

    在此之前需要将表的内容写进数据库

    $ python manage.py makemigrations TestModel  # 让 Django 知道我们在我们的模型有一些变更
    $ python manage.py migrate TestModel   # 创建表结构
    
    • 1
    • 2

    自定义表单

    自定义管理页面来取代默认的页面,比如在add页面只想显示name和email,修改admin.py

    class ContactAdmin(admin.ModelAdmin):
        fields = ('name', 'email')
     
    admin.site.register(Contact, ContactAdmin)
    admin.site.register([Test, Tag])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ORM单表实例

    先创一个project

    django-admin startproject app01
    # 记得在Installed_app 加入app01
    
    # __init__.py:
    import pymysql
    pymysql.install_as_MySQLdb()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    创建模型

    # app01/models.py
    class Book(models.Model): 
        id = models.AutoField(primary_key=True) # id 会自动创建,可以手动写入
        title = models.CharField(max_length=32) # 书籍名称
        price = models.DecimalField(max_digits=5, decimal_places=2) # 书籍价格 
        publish = models.CharField(max_length=32) # 出版社名称 
        pub_date = models.DateField() # 出版时间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用命令执行命令

    $ python3 manage.py migrate   # 创建表结构
    
    $ python3 manage.py makemigrations app01  # 让 Django 知道我们在我们的模型有一些变更
    $ python3 manage.py migrate app01   # 创建表结构
    
    • 1
    • 2
    • 3
    • 4

    数据库添加:

    规则配置:

    # app01/urls.py
    from django.contrib import admin
    from django.urls import path
    from . import views
     
    urlpatterns = [
        path('add_book/', views.add_book),
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    使用模型实例化对象

    # app01/views.py
    def add_book(request):
        book = models.Book(title="菜鸟教程",price=300,publish="菜鸟出版社",pub_date="2008-8-8") 
        book.save()
        return HttpResponse("

    数据添加成功!

    "
    )
    • 1
    • 2
    • 3
    • 4
    • 5

    使用ORM提供的objects.create() (推荐)

    	books = models.Book.objects.create(title="如来神掌",price=200,publish="功夫出版社",pub_date="2010-10-10")
    	
    
    • 1
    • 2

    查找

    使用all()来查询所有内容,返回的QuerySet()类型,里面放的是模型类的对象,可以用索引下标取出模型类的对象。

    def search_book(request):
    	books = models.Book.objects.all()
    	for i in books:
    		print (i.title)
    
    • 1
    • 2
    • 3
    • 4

    filter() 方法用于查询符合条件的数据,pk表示primary key =3相当于id =3 (不用id因为有内置函数)

    	books = models.Book.obeject.filter(pk=5)
    	# 查询价格为200或者300的数据 filter 中运算符号只能使用等于号 = ,不能使用大于号 > ,小于号 < ,等等其他符号。
    __in 用于读取区间,= 号后面为列表 。__gt大于。__lt小于,__range 范围。 __contains包含,
    __startwith
        books = models.Book.objects.filter(price__in=[200,300])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    exclude 方法用于查询不符合条件的数据
    get()方法用于查询符合条件的返回模型类的对象只能有一个。如果没有或者超过会有异常。
    order_by() 对查询结果进行排序。

    	books= models.Book.objects.order_by("price")  # 升序排列 "-price" 降序排列
    
    • 1

    count() 查询所有数据的数量
    first() 返回第一条数据
    exist() 判断查询的结果集是否含有数据

    删除

    使用object,返回的是受影响的行数

    	books=models.Book.objects.filter(pk=8).first().delete()
    
    • 1

    注意,删除一个对象的时候会删除与它相关的外键对象

    修改

    使用对象.属性 = 更改的属性值,对象.save()

    	books = models.Book.objects.filter(pk=7).first()
    	books.price= 400
    	books.save()
    
    • 1
    • 2
    • 3

    或者使用update () 推荐

    	books= models.Book.objects.filter(pk__in=[7,8]).update(price=888)
    
    • 1

    ORM多表实例

    表和表之间的关系可以分为:一对一,一对多,多对多。
    创建模型

    # models.py
    from django.db import  models
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=5, decimal_places=2)
        pub_date = models.DateField()
        publish = models.ForeignKey("Publish", on_delete=models.CASCADE)
        authors = models.ManyToManyField("Author")
    
    
    class Publish(models.Model):
        name = models.CharField(max_length=32)
        city = models.CharField(max_length=64)
        email = models.EmailField()
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
        age = models.SmallIntegerField()
        au_detail = models.OneToOneField("AuthorDetail", on_delete=models.CASCADE)
    
    
    class AuthorDetail(models.Model):
        gender_choices = (
            (0, "女"),
            (1, "男"),
            (2, "保密"),
        )
        gender = models.SmallIntegerField(choices=gender_choices)
        tel = models.CharField(max_length=32)
        addr = models.CharField(max_length=64)
        birthday = models.DateField()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    通过上述模型可以知道一共创建了4个表。
    其中外键在一对多的多中设置:models.ForeignKey(“关联类名”,on_delete=models.CASCADE)

    插入数据

    mysql添加数据

    insert into app01_publisher(name,city,email) values ("1","2","3")
    
    • 1

    ORM添加数据
    一对多(外键),获取对象,给属性传出对象

    	pub_obj = models.Pulish.objects.filter(pk=1).first()
    	book= models.Book.object.create(title="1"....)
    
    • 1
    • 2

    获取对象的id,传出对象的id

    	pub_obj = models.Pulish.objects.filter(pk=1).first()
    	pk=pub_obj.pk
    	book=models.objects.create("",publish_id=pk)
    
    • 1
    • 2
    • 3

    多对多(manytomanyfield):在第三张表新增数据
    获取作者对象,获取书籍对象,给属性add方法

    	# 获取作者对象
    	chong= models.Author.objects.filter(name="123").first()
    	ying= models.Author.objects.filter(name="345").first()
    	# 获取书籍对象
    	book =models.Book.objects.filter(title="1234").first()
    	book.authors.add(chong,ying)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    传对象id形式

    	chong= models.Author.objects.filter(name="123").first()
    	pk=chong.pk
    	book= models.Book.objects.filter(titile="12").first()
    	book.authors.add(pk)
    
    • 1
    • 2
    • 3
    • 4

    关联管理器(对象调用)

    前提:多对多(双向),一对多(只能反向)
    格式:

    正向:属性名
    反向:小写类名加——set
    
    • 1
    • 2

    add() 用于多对多,把指定模型对象添加到关联对象集,若是在一对多,只能传对象,不能传id

    # 传对象
    book_obj= models.Book.objects.get(id=10)
    author_list=models.Author.objects.filter(id__gt=2)
    book_obj.author.add(*author_list) # 将id大于2的作者添加作者集合
    
    #传对象id
    book_obj.authors.add(*[1,3]) # 将id=1,id=3对象添加到集合
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    反向:小写表名_set

    ying= models.Author.objects.filter(name="123").first()
    book= models.Book.objects.filter(title="456").first()
    ying.book_set.add(book)
    
    • 1
    • 2
    • 3

    ORM查询

    查询主键为10书籍的出版社的城市(正向)

    book=models.Book.objects.filter(pk=10).first()
    res=book.publish.city
    
    
    • 1
    • 2
    • 3

    查找123出版社的书籍名

    pub=models.Publish.objects.filter(name="123").first()
    res = pub.book_set.all()
    for i in res:
    	print(i.title)
    
    • 1
    • 2
    • 3
    • 4

    ORM 多表实例

    聚合查询

    聚合查询是对一组值执行计算并返回单个值
    aggregate()是一个终止子句,生成的一个汇总值,相当于count
    aggregate(别名 = 聚合函数名("属性名称“))

    from django.db.models import Avg,Max,Min,Count,Sum # 引入函数
    res = models.Book.objects.aggregate(Avg("price"))
    print(res,type(res))                                                                                                                                                                                           
    
    • 1
    • 2
    • 3

    分组查询

    一般都要用到聚合函数。annotate
    准备模型

    # models.py
    class Emp(models.Model): 
        name = models.CharField(max_length=32) 
        age = models.IntegerField()
        salary = models.DecimalField(max_digits=8, decimal_places=2)
        dep = models.CharField(max_length=32) 
        province = models.CharField(max_length=32)
    
    class Emps(models.Model): 
        name = models.CharField(max_length=32) 
        age = models.IntegerField() 
        salary =     models.DecimalField(max_digits=8, decimal_places=2) 
        dep = models.ForeignKey("Dep", on_delete=models.CASCADE)
        province = models.CharField(max_length=32) 
    class Dep(models.Model): 
        title = models.CharField(max_length=32) 
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    统计每一个出版社最便宜的书的价格

    res= models.Publish.objects.values("name").annotate(in_price=Min("book_price")
    print(res)
    
    • 1
    • 2

    统计每一本书的作者个数

    res= models.Book.objects.annotate(c=Count("authors__name")).values("title","c)
    print(res)
    
    • 1
    • 2

    统计以菜开头的书的作者个数

    res= models.Book.objects.filter(title__startwith="菜").annotate(c=Count("authors_name")).values("title","c")
    
    • 1

    根据一本图书作者数量的多少对查询集进行降序

    res=models.Book.objects.annotate(c=Count("authors_name")).order_by("-c").values("title","c")
    
    • 1

    查询各个作者的书的总价格

    res= models.Author.objects.annotate(all=Sum("book__price")).values("name","all")
    print(res)
    
    • 1
    • 2

    F()查询

    F()的实例在查询中引用字段,来比较同一个model实例不同字段的值。
    想要对两个字段的值做比较就得用F()

    from django.db.models import F
    # 用法: F("字段名称")
    
    
    • 1
    • 2
    • 3

    查询工资大于年龄的人:

    book=models.Emp.objects.filter(salary__gt=F("age")).value("name","age")
    
    • 1

    Q()查询

    from django.db.models import Q
    # Q(条件判断)
    Q(title_startswith="菜“)
    
    • 1
    • 2
    • 3

    之前构造的过滤器多个条件关系书and,如果执行复杂的查询(or),就可以使用Q
    查询价格大于350或者名称以菜开头的书籍的名称和价格

    res=models.Book.objects.filter(Q(price__gt=350)|Q(title__startwith="菜")).values("title","price")
    
    • 1

    Django Form组件

    对页面进行初始化,生成html标签,也可以对提交的数据进行检验。

    # app01/My_forms.py
    from django import forms
    from django.core.exceptions import ValidationError
    from app01 import models
    
    class EmpForm(forms.Form):
        name = forms.CharField(min_length=4, label="姓名", error_messages={"min_length": "你太短了", "required": "该字段不能为空!"})
        age = forms.IntegerField(label="年龄")
        salary = forms.DecimalField(label="工资")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    app01/views.py

    from django.shortcuts import render, HttpResponse
    from app01.My_Forms import EmpForm
    from app01 import models
    from django.core.exceptions import ValidationError
    # Create your views here.
    
    
    def add_emp(request):
        if request.method == "GET":
            form = EmpForm()
            return render(request, "add_emp.html", {"form": form})
        else:
            form = EmpForm(request.POST)
            if form.is_valid():  # 进行数据校验
                # 校验成功
                data = form.cleaned_data  # 校验成功的值,会放在cleaned_data里。
                data.pop('r_salary')
                print(data)
    
                models.Emp.objects.create(**data)
                return HttpResponse(
                    'ok'
                )
                # return render(request, "add_emp.html", {"form": form})
            else:
                print(form.errors)    # 打印错误信息
                clean_errors = form.errors.get("__all__")
                print(222, clean_errors)
            return render(request, "add_emp.html", {"form": form, "clean_errors": clean_errors})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    add_emp.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
     
    <h3>添加员工</h3>
     
    {#1、自己手动写HTML页面#}
    <form action="" method="post">
        <p>姓名:<input type="text" name="name"></p>
        <p>年龄:<input type="text" name="age"></p>
        <p>工资:<input type="text" name="salary"></p>
        <input type="submit">
    </form>
     
    {#2、通过form对象的as_p方法实现#}
    {#
    #} {# {% csrf_token %}#} {# {{ form.as_p }}#} {# #} {##}
    {#3、手动获取form对象的字段#} {#
    #} {# {% csrf_token %}#} {#
    #} {# #} {# {{ form.name }} {{ form.name.errors.0 }}#} {#
    #}
    {#
    #} {# #} {# {{ form.age }} {{ form.age.errors.0 }}#} {#
    #}
    {#
    #} {# #} {# {{ form.salary }} {{ form.salary.errors.0 }}#} {#
    #}
    {# #} {##}
    {#4、用for循环展示所有字段#} {#
    #} {# {% csrf_token %}#} {# {% for field in form %}#} {#
    #} {# #} {# {{ field }} {{ field.errors.0 }}#} {#
    #}
    {# {% endfor %}#} {# #} {##}
    </body> </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    用户认证(Auth)

    创建用户对象的三种方法:
    create():创建一个普通用户,密码是明文的。
    create_user():创建一个普通用户,密码是密文的。
    create_superuser():创建一个超级用户,密码是密文的,要多传一个邮箱 email 参数。

    
    from django.contrib import auth # 认证模块
    from django.contrib.auth.models import User # 对应数据库
    User.objects.create_user(username='runbooo',password='123')
    
    • 1
    • 2
    • 3
    • 4

    验证用户的用户名和密码使用 authenticate() 方法,从需要 auth_user 表中过滤出用户对象。
    使用前要导入:

    from django.contrib import auth # 认证模块
    def login(request):
        if request.method == "GET":
            return render(request, "login.html")
        username = request.POST.get("username")
        password = request.POST.get("pwd")
        valid_num = request.POST.get("valid_num")
        keep_str = request.session.get("keep_str")
        if keep_str.upper() == valid_num.upper():
            user_obj = auth.authenticate(username=username, password=password)
            print(user_obj.username)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    cookies与session

    cookies是存储在客户端计算机上的文本文件,保留了各种跟踪信息。识别返回用户包含以下步骤:1.服务器脚本向浏览器发送一组cookies 2.浏览器将信息存储在本地计算机 3.当下一次发送请求的时候,浏览器会把cookies发送给服务器,服务器用来识别用户。
    http是无状态协议,服务器会自动不保留任何记录,但仍有三种方式维持会话

    cookies

    一个服务器分配一个唯一的session id作为cookie.在开发中,使用session来完成会话跟踪,session底层依赖cookie技术

    # 设置cookie
    rep.set_cookir(key,value)
    rep.set_signed_cookie(key,value,salt)
    
    # 获取cookie
    request.COOKIES.get(key)
    
    #删除cookie
    rep=HttpResponse|| render || redirect
    rep.delete_cookie(key)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    models.py

    class UserInfo(models.Model):
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
    
    • 1
    • 2
    • 3

    urls.py

    from django.contrib import admin
    from django.urls import path
    from cookie import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
        path('logout/', views.logout),
        path('order/', views.order)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    views.py

    def login(request):
        if request.method == "GET":
            return render(request, "login.html")
        username = request.POST.get("username")
        password = request.POST.get("pwd")
    
        user_obj = models.UserInfo.objects.filter(username=username, password=password).first()
        print(user_obj.username)
    
        if not user_obj:
            return redirect("/login/")
        else:
            rep = redirect("/index/")
            rep.set_cookie("is_login", True)
            return rep
            
    def index(request):
        print(request.COOKIES.get('is_login'))
        status = request.COOKIES.get('is_login') # 收到浏览器的再次请求,判断浏览器携带的cookie是不是登录成功的时候响应的 cookie
        if not status:
            return redirect('/login/')
        return render(request, "index.html")
    
    
    def logout(request):
        rep = redirect('/login/')
        rep.delete_cookie("is_login")
        return rep # 点击注销后执行,删除cookie,不再保存用户状态,并弹到登录页面
        
    def order(request):
        print(request.COOKIES.get('is_login'))
        status = request.COOKIES.get('is_login')
        if not status:
            return redirect('/login/')
        return render(request, "order.html")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
     
    <h3>用户登录</h3>
    <form action="" method="post">
        {% csrf_token %}
        <p>用户名: <input type="text" name="username"></p>
        <p>密码: <input type="password" name="pwd"></p>
        <input type="submit">
    </form>
     
     
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
     
     
    <h2>index 页面。。。</h2>
     
     
    <a href="/logout/">注销</a>
     
    </body>
    </html>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    order.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
     
     
    <h2>order 页面。。。</h2>
     
     
    <a href="/logout/">注销</a>
     
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    session

    session:保存在服务端的键值对。
    原理:1.第一次请求获取登录页面login 2.输入正确,服务器响应浏览器index页面和一个键为sessionid,值为cookie,即set_cookie 3.服务器内部在django.session表中记录一条数据(key,data,date) 4.第三次请求资源时,携带cookie,服务器从表中根据随机字符串取出数据,使用。

    django中间件

    中间件是修改request或者response对象的钩子。浏览器从请求到响应的过程中,django需要通过很多中间件来处理。其作用为:修改请求,修改响应。一般配置在settings.py /MIDDLEWARE列表中。

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    自定义中间件

    自定义中间件,分别是:

    process_request(self,request)
    process_view(self,request,view_func,view_args,view_kwargs)
    process_exception(self,request,exception)
    process_response(self,request,response)
    
    • 1
    • 2
    • 3
    • 4

    app01/middlewares.py

    from django.utils.deprecation import MiddlewareMixin
    
    class MD1(MiddlewareMixin):
    	pass
    
    • 1
    • 2
    • 3
    • 4

    settings.py /MIDDLEWARE:

    	'app01.middlewares.MD1'
    
    • 1

    自定义中间件类的方法有process_request,process_response.
    middlewares.py

    class MD1(MiddlewareMixin):
        def process_request(self, request):
           print("md1  process_request 方法。", id(request)) #在视图之前执行
    
    • 1
    • 2
    • 3

    process_request 方法,返回值可以是None也可以是HttpResponse对象。如果是None,正常流程走,交给下一个中间件处理;如果是对象,将不执行后续视图函数,直接以其为起点,倒序执行中间件。

    class MD1(MiddlewareMixin):
        def process_request(self, request):
            print("md1  process_request 方法。", id(request)) #在视图之前执行
    
    
        def process_response(self,request, response): :#基于请求响应
            print("md1  process_response 方法!", id(request)) #在视图之后
            return response
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    视图(FBV与CBV)

    FBV:基于函数的视图,在视图里使用函数处理请求
    CBV: 基于类的视图,就是在视图里使用类处理请求。
    前面都是使用FBV方法来处理请求的。
    而基于类的视图

    from django.views import View
    
    • 1

    urls.py

    urlpatterns = [
    	path("login/",views.Login.as_view()),
    ]
    
    • 1
    • 2
    • 3

    url是将一个请求分配给可调用的函数,而不是一个类。通过父类View的静态方法as_view().as_view基于类的外部接口,返回一个视图函数,调用后请求会传递给dispatch()。

    # views.py
    from django.shortcuts import render,HttpResponse
    from django.views import View
    
    class Login(View):
        def get(self,request):
            return HttpResponse("GET 方法")
    
        def post(self,request):
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            if user == "runoob" and pwd == "123456":
                return HttpResponse("POST 方法")
            else:
                return HttpResponse("POST 方法 1")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    inpaint-anything:分割任何东西遇到图像修复
    Spring IoC 和 AOP
    【微信小程序】轻松实现轮播图,视图容器和基本内容组件
    在MoneyPrinterPlus中使用本地chatTTS语音模型
    计算机毕业设计(附源码)python招聘信息管理平台
    springboot+基于web的传染病信息管理系统的设计与实现 毕业设计-附源码221124
    “那天开始,我拒绝了油盐糖”
    【从零开始的Java开发】2-9-1 JavaScript入门:语法、JS对表单元进行设置、事件与DOM
    RTMP协议解析
    DT建模快速入门
  • 原文地址:https://blog.csdn.net/QAZJOU/article/details/126227188