Django框架进阶7 forms组件(pycharm内置测试环境Python Console), cookie与session操作

forms组件

写一个注册页面 获取用户输入的用户名和密码
用户点击注册发送到后端做用户名密码的校验
用户名中不能包含金瓶mei     不符合社会主义核心价值观
密码不能为空            你个DSB,密码怎么能为空

1.手写获取用户输入的前端页面代码                    渲染页面
2.后端获取用户数据并做合法性校验                    校验数据
3.将校验之后的结果渲染到前端页面                    展示信息

不用forms组件代码:

app01/views.py

from django.shortcuts import render,HttpResponse

# Create your views here.
def register(request):
    error_dic = {‘username‘:‘‘,‘password‘:‘‘}
    if request.method == ‘POST‘:
        username = request.POST.get(‘username‘)
        password = request.POST.get(‘password‘)
        if ‘金瓶mei‘ in username:
            error_dic[‘username‘] = ‘不符合社会主义核心价值观‘
        if not password:
            error_dic[‘password‘] = ‘密码不能为空‘
    return render(request,‘register.html‘,locals())

templates/register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<form action="" method="post">
    <p>username:
        <input type="text" name="username">
        <span style="color: red">{{ error_dic.username }}</span>
    </p>
    <p>password:
        <input type="text" name="password">
        <span style="color: red">{{ error_dic.password }}</span>
    </p>
    <input type="submit">
</form>
</body>
</html>

pycharm内置测试环境:Python Console

forms组件

1.渲染页面

2.校验数据

3.展示信息

需要先写一个类

from django import forms

class MyRegForm(forms.Form):
    # 用户名最少3位  最多8位
    username = forms.CharField(max_length=8,min_length=3)
    password = forms.CharField(max_length=8,min_length=3)
    # email字段必须填写符合邮箱格式的数据
    email = forms.EmailField()

如何校验数据

# 1.传入待校验的数据  用自己写的类 传入字典格式的待校验的数据
form_obj = views.MyRegForm({‘username‘:‘jason‘,‘password‘:‘12‘,‘email‘:‘123456‘})
# 2.判断数据是否符合校验规则
form_obj.is_valid()  # 该方法只有在所有的数据全部符合校验规则才会返回True
False
# 3.如何获取校验之后通过的数据
form_obj.cleaned_data
{‘username‘: ‘jason‘}
# 4.如何获取校验失败及失败的原因
form_obj.errors
{
 ‘password‘: [‘Ensure this value has at least 3 characters (it has 2).‘],
 ‘email‘: [‘Enter a valid email address.‘]
 }
# 5.注意 forms组件默认所有的字段都必须传值 也就意味着传少了是肯定不行的 而传多了则没有任何关系 只校验类里面写的字段 多传的直接忽略了
form_obj = views.MyRegForm({‘username‘:‘jason‘,‘password‘:‘123456‘})
form_obj.is_valid()
Out[12]: False
form_obj.errors
Out[18]: {‘email‘: [‘This field is required.‘]}

form_obj = views.MyRegForm({‘username‘:‘jason‘,‘password‘:‘123456‘,"email":‘[email protected]‘,"hobby":‘hahahaha‘})
form_obj.is_valid()
Out[14]: True
form_obj.cleaned_data
Out[15]: {‘username‘: ‘jason‘, ‘password‘: ‘123456‘, ‘email‘: ‘[email protected]‘}
form_obj.errors
Out[16]: {}

如何渲染页面

先写一个继承forms的类

forms组件只帮你渲染获取用户输入(输入 选择 下拉 文件)的标签  不渲染按钮和form表单标签

渲染出来的每一个input提示信息都是类中字段首字母大写

{#<p>第一种渲染方式:多个p标签  本地测试方便  封装程度太高了  不便于扩展</p>#}
{#{{ form_obj.as_p }}#}
{#{{ form_obj.as_ul }}#}
{#{{ form_obj.as_table }}#}

{#<p>第二种渲染方式:扩展性较高  书写较为繁琐</p>#}
{#<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>     {# 给label赋id值 #}
{#{{ form_obj.username }}#}
{#{{ form_obj.password.label }}{{ form_obj.password }}#}
{#{{ form_obj.email.label }}{{ form_obj.email }}#}

<p>第三种渲染方式 推荐使用</p>
{% for form in form_obj %}
    <p>{{ form.label }}{{ form }}</p>
{% endfor %}

如何渲染错误信息

前端

<form action="" method="post" novalidate>   {# 取消前端校验,前端校验只能显示第一个错误,而且不安全 #}
        {% for form in form_obj %}
            <p>
             {{ form.label }}{{ form }}      {# 另外注意这个是模板语法 .0索引不会因为对象为空出现超出报错#}
              <span>{{ form.errors.0 }}</span>  {# 容器类型(此处为列表)会自动被渲染成ul套li形式,加.0固定写法,拿到内部信息 #}
            </p>
    {% endfor %}
    <input type="submit">

</form>

后端

def reg(request):
    # 1.先生成一个空的类对象
    form_obj = MyRegForm()
    if request.method == ‘POST‘:
        # 3 获取用户数据并交给forms组件校验  request.POST 字典类型
        form_obj = MyRegForm(request.POST)
        # 4 获取校验结果
        if form_obj.is_valid():
            return HttpResponse(‘数据没问题‘)
        else:
            # 5 获取校验失败的字段和提示信息
            print(form_obj.errors)

    # 2直接将该对象传给前端页面
    return render(request,‘reg.html‘,locals())

数据校验一个前后端都得有 但是前端的校验弱不禁风 可有可无
而后端的校验则必须非常全面

如何取消浏览器自动帮我们校验的功能
form表单取消前端浏览器自动校验功能

<form action="" method="post" novalidate>

常用参数

label   input的提示信息
error_messages    自定义报错的提示信息
required    设置字段是否允许为空
initial    设置默认值
widget    控制type类型及属性

widget=forms.widgets.TextInput(attrs={‘class‘:‘form-control c1 c2‘})
widget=forms.widgets.PasswordInput(attrs={‘class‘:‘form-control‘})

例:

class MyRegForm(forms.Form):
    # 用户名最少3位  最多8位
    username = forms.CharField(max_length=8,min_length=3,label=‘用户名‘,   #label不写,默认为字段名首字母大写
                               error_messages={
                                   ‘max_length‘:‘用户名最长8位‘,
                                    ‘min_length‘:‘用户名最短3位‘,
                                   ‘required‘:‘用户名不能为空‘
                               },required=False, # 可以不填,为空
                               initial=‘jason‘,  # 默认值
                               widget=forms.widgets.TextInput(attrs={‘class‘:‘form-control c1 c2‘})
                               )
    password = forms.CharField(max_length=8,min_length=3,label=‘密码‘,
                               widget=forms.widgets.PasswordInput(attrs={‘class‘:‘form-control‘}))
    # email字段必须填写符合邮箱格式的数据
    email = forms.EmailField(label=‘邮箱‘,error_messages={
        ‘required‘:‘邮箱必填‘,
        ‘invalid‘:‘邮箱格式不正确‘
    })

钩子函数

全局钩子(针对多个字段)

  校验密码与确认面是否一致

局部钩子(针对单个字段)

  校验用户名不能包含666

    # 全局钩子  注意如果有错误,页面并不会刷新,输入的数据还在,因为下方reg函数
    def clean(self):    # 钩子函数已被封装,固定名。会在上面MyRegForm输入参数第一层校验通过后,进行第二层校验
        # 校验密码和确认密码是否一致
        password = self.cleaned_data.get(‘password‘)
        confirm_password = self.cleaned_data.get(‘confirm_password‘)
        if not password == confirm_password:
            # 展示提示信息
            self.add_error(‘confirm_password‘,‘两次密码不一致‘)
        return self.cleaned_data    # 拿全局数据,要返回全局数据
    # 局部钩子
    def clean_username(self):
        username = self.cleaned_data.get(‘username‘)
        if ‘666‘ in username:
            self.add_error(‘username‘,‘光喊666是不行的‘)
        return username     # 拿了局部数据,要返回局部数据

app01/views.py

from django.shortcuts import render,HttpResponse

# Create your views here.
def register(request):
    error_dic = {‘username‘:‘‘,‘password‘:‘‘}
    if request.method == ‘POST‘:
        username = request.POST.get(‘username‘)
        password = request.POST.get(‘password‘)
        if ‘金瓶mei‘ in username:
            error_dic[‘username‘] = ‘不符合社会主义核心价值观‘
        if not password:
            error_dic[‘password‘] = ‘密码不能为空‘
    return render(request,‘register.html‘,locals())

from django import forms
from django.forms import widgets
from django.core.validators import RegexValidator   # 导入正则表达式

class MyRegForm(forms.Form):
    # 用户名最少3位  最多8位
    username = forms.CharField(max_length=8,min_length=3,label=‘用户名‘,   #label不写,默认为字段名首字母大写
                               error_messages={
                                   ‘max_length‘:‘用户名最长8位‘,
                                    ‘min_length‘:‘用户名最短3位‘,
                                   ‘required‘:‘用户名不能为空‘
                               },required=False, # 可以不填,为空
                               initial=‘jason‘,  # 默认值
                               # widget=forms.widgets.TextInput(attrs={‘class‘:‘form-control c1 c2‘})
                               )
    password = forms.CharField(max_length=8,min_length=3,label=‘密码‘,
                               # widget=forms.widgets.PasswordInput(attrs={‘class‘:‘form-control‘})
                               )
    confirm_password = forms.CharField(max_length=8,min_length=3,label=‘密码‘,
                               # widget=forms.widgets.PasswordInput(attrs={‘class‘:‘form-control‘})
                                       )
    # email字段必须填写符合邮箱格式的数据
    email = forms.EmailField(label=‘邮箱‘,error_messages={
        ‘required‘:‘邮箱必填‘,
        ‘invalid‘:‘邮箱格式不正确‘
    })

    phone = forms.CharField(
        validators=[
            RegexValidator(r‘^[0-9]+$‘,‘请输入数字‘),
            RegexValidator(r‘^159[0-9]+$‘,‘数字必须以159开头‘)
        ]
    )

    # 全局钩子  注意如果有错误,页面并不会刷新,输入的数据还在,因为reg函数
    def clean(self):    # 钩子函数已被封装,固定名。会在上面MyRegForm输入参数第一层校验通过后,进行第二层校验
        # 校验密码和确认密码是否一致
        password = self.cleaned_data.get(‘password‘)
        confirm_password = self.cleaned_data.get(‘confirm_password‘)
        if not password == confirm_password:
            # 展示提示信息
            self.add_error(‘confirm_password‘,‘两次密码不一致‘)
        return self.cleaned_data    # 拿全局数据,要返回全局数据

    # 局部钩子
    def clean_username(self):
        username = self.cleaned_data.get(‘username‘)
        if ‘666‘ in username:
            self.add_error(‘username‘,‘光喊666是不行的‘)
        return username     # 拿了局部数据,要返回局部数据

def reg(request):
    # 1.先生成一个空的类对象
    form_obj = MyRegForm()
    if request.method == ‘POST‘:
        # 3 获取用户数据并交给forms组件校验  request.POST
        form_obj = MyRegForm(request.POST)
        # 4 获取校验结果
        if form_obj.is_valid():
            return HttpResponse(‘数据没问题‘)
            # return render(request, ‘reg.html‘, locals())

        else:
            # 5 获取校验失败的字段和提示信息
            print(form_obj.errors)

    # 2直接将该对象传给前端页面
    return render(request,‘reg.html‘,locals())

templates/reg.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{#<p>第一种渲染方式:多个p标签  本地测试方便  封装程度太高了  不便于扩展</p>#}
{#{{ form_obj.as_p }}#}
{#{{ form_obj.as_ul }}#}
{#{{ form_obj.as_table }}#}

{#<p>第二种渲染方式:扩展性较高  书写较为繁琐</p>#}
{#<label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>     {# 给label赋id值 #}
{#{{ form_obj.username }}#}
{#{{ form_obj.password.label }}{{ form_obj.password }}#}
{#{{ form_obj.email.label }}{{ form_obj.email }}#}

<p>第三种渲染方式 推荐使用</p>
<form action="" method="post" novalidate>   {# 取消前端校验,前端校验只能显示第一个错误,而且不安全 #}
        {% for form in form_obj %}
            <p>
             {{ form.label }}{{ form }}
              <span>{{ form.errors.0 }}</span>  {# 容器类型(此处为列表)会自动被渲染成ul套li形式,加.0固定写法,拿到内部信息 #}
            </p>
    {% endfor %}
    <input type="submit">

</form>
</body>
</html>

forms补充知识点

正则校验

from django import forms
from django.core.validators import RegexValidator   # 导入正则表达式
class MyRegForm(forms.Form):
    phone = forms.CharField(
        validators=[
            RegexValidator(r‘^[0-9]+$‘,‘请输入数字‘),
            RegexValidator(r‘^159[0-9]+$‘,‘数字必须以159开头‘)
        ]
    )

渲染选择框,下拉框

from django import forms
from django.forms import widgets
from django.core.validators import RegexValidator

    ################了解知识点(指定去哪里拷贝即可)################
    gender = forms.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )

    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )
    hobby1 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )
    hobby2 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

django操作cookie与session

cookie与session的作用
  保存信息

当你第一次登陆成功之后 服务端给你返回了一个随机字符串
保存客户端浏览器上 之后再次朝服务端发请求 只需要携带该随机字符串
服务端就能够识别当前用户身份
超时时间的概念

cookie虽然是保存在客户端的浏览器上的 但是是服务端设置的
浏览器也是可以拒绝服务端对要求 不保存cookie

cookie
  保存在客户端浏览器上的键值对

return HttpResponse(‘...‘)
return render(...)
return redirect(...)

# 变形
obj = HttpResponse(‘...‘)
return obj
obj1 = render(...)
return obj1
obj2 = redirect(...)

#设置cookie
obj.set_cookie()  # obj一定要是HttpResponse类直接或间接继承对象
#获取cookie
request.COOKIES.get()
#删除cookie
obj.delete_cookie()

获取请求路径

    print(‘request.path_info:‘,request.path_info)  # 只拿路径部分 不拿参数
    print(‘request.get_full_path():‘,request.get_full_path())  # 路径加参数
        request.path_info: /home/

        request.get_full_path(): /home/?username=jason&password=123

例:

#装饰器模板
from functools import wraps  

def login_auth(func):
    @wraps(func)  # 修正装饰器文档功能
    def inner(request,*args,**kwargs):
        print(‘path_info:‘,request.path_info)   # 只拿路径部分 不拿参数
        print(‘get_full_path():‘,request.get_full_path())   #路径加参数
        # 执行被装饰函数之前你可以做的事情
        target_url = request.path_info
        if request.COOKIES.get(‘username‘):
            res = func(request,*args,**kwargs)
            return res
        else:
            return redirect(‘/login/?next=%s‘%target_url)
    return inner

def login(request):
    if request.method == ‘POST‘:
        username = request.POST.get(‘username‘)
        password = request.POST.get(‘password‘)
        if username == ‘jason‘ and password == ‘123‘:
            # target_url = request.GET.get(‘next‘,‘/home/‘) # 直接设置默认值也可以
            target_url = request.GET.get(‘next‘)  # 获取地址栏中的信息
            # 判断用户登录之前是否有想要访问的url
            if target_url:

                # 保存用户登录状态
                obj = redirect(target_url)
            else:
                obj = redirect(‘/home/‘)
            # 设置cookie
            obj.set_cookie(‘username‘,‘jason666‘,max_age=3)   # 不可设中文  max_age设置cookie3秒后超时
            return obj

    return render(request,‘login.html‘)

@login_auth
def home(request):
    # 校验浏览器是否有对应的cookie
    # if request.COOKIES.get(‘username‘):
    #     print(request.COOKIES)
    #     return HttpResponse(‘我是home页面 只有登录的用户才能访问‘)
    # else:
    #     return redirect(‘/login/‘)
    return HttpResponse(‘我是home页面 只有登录的用户才能访问‘)

@login_auth
def index(request):
    return HttpResponse(‘我是index页面 只有登录的用户才能访问‘)

@login_auth
def demo(request):
    return HttpResponse(‘我是demo页面 只有登录的用户才能访问‘)

@login_auth
def logout(request):
    obj = HttpResponse(‘注销了‘)
    obj.delete_cookie(‘username‘)
    return obj

session
保存在服务端上的键值对

设置

request.session[‘key‘] = value
"""
1.django内部会自动生成一个随机字符串
2.去django_session表中存储数据 键就是随机字符串 值是要保存的数据(中间件干的)
3.将生成好的随机字符串返回给客户端浏览器 浏览器保存键值对
sessionid 随机字符串
"""

获取

request.session.get(‘key‘)
"""
1.django会自动取浏览器的cookie查找sessionid键值对 获取随机字符串
2.拿着该随机字符串取django_session表中比对数据
3.如果比对上了 就将随机字符串对应的数据获取出来并封装到request.session供用户调用
"""

django中默认的session超时时间为14天

例:

def set_session(request):
    request.session[‘username‘] = ‘jason666‘
    return HttpResponse(‘set_session‘)

from django.http import JsonResponse
def get_session(request):
    print(request.session)
    print(request.session.get(‘username‘))
    return HttpResponse(‘get_session‘)

# 设置会话Session和Cookie的超时时间
request.session.set_expiry(value)
* 如果value是个整数,session会在些秒数后失效。
* 如果value是个datatime或timedelta,session就会在这个时间后失效。
* 如果value是0,用户关闭浏览器session就会失效。
* 如果value是None,session会依赖全局session失效策略。

例:

def set_session(request):
    request.session[‘username‘] = ‘egonDSB‘
    request.session.set_expiry(5)   # session有效期为5秒
    return HttpResponse(‘set_session‘)

from django.http import JsonResponse
def get_session(request):
    print(request.session)
    print(request.session.get(‘username‘))
    return HttpResponse(‘get_session‘)
# 删除当前会话的所有Session数据
request.session.delete()
  
# 删除当前的会话数据并删除会话的Cookie。 推荐使用
request.session.flush()
这用于确保前面的会话数据不可以再次被用户的浏览器访问
例如,django.contrib.auth.logout() 函数中就会调用它。

例:

def set_session(request):
    request.session[‘name‘] = ‘egon‘
    return HttpResponse(‘set_session‘)

from django.http import JsonResponse
def get_session(request):
    print(request.session.get(‘name‘))
    return HttpResponse(‘get_session‘)

def del_session(request):
    request.session.flush()
    return HttpResponse(‘注销了‘)

session是保存在服务端

django_session表你还可以把它当成是一个临时的仓库

注意:

此处数据是根据浏览器的不同创建的,同一种浏览器只会有一条cookie数据

原文地址:https://www.cnblogs.com/ludingchao/p/12189450.html

时间: 2024-10-04 06:01:21

Django框架进阶7 forms组件(pycharm内置测试环境Python Console), cookie与session操作的相关文章

len(x) 击败 x.len(),从内置函数看 Python 的设计思想

内置函数是 Python 的一大特色,用极简的语法实现很多常用的操作. 它们预先定义在内置命名空间中,开箱即用,所见即所得.Python 被公认是一种新手友好型的语言,这种说法能够成立,内置函数在其中起到了极关键的作用. 举个例子,求字符串 x 的长度,Python 的写法是 len(x) ,而且这种写法对列表.元组和字典等对象也同样适用,只需要传入对应的参数即可.len() 函数是共用的. 这是一种极简哲学的体现:Simple is better than complex. 但是,有些语言并不

Django框架进阶6 多对多三种创建方式, Ajax, Content-Type前后端传输数据编码格式, Ajax发送文件数据, django内置的序列化功能, Ajax结合sweetalert实现删除二次确认, 批量插入数据, 自定义分页器, ajax结合sweetalert实现删除二次确认

多对多三种创建方式 1.全自动(较为常用) class Book(models.Model): title = models.CharField(max_length=32) authors = models.ManyToManyField(to='Author') # orm就会自动帮你创建第三张表 class Author(models.Model): name = models.CharField(max_length=32) ''' 好处:第三张表自己创建 不足之处:第三张表无法扩展额外

Django框架基础之Form组件

服务端假设所有用户提交的数据都是不可信任的,所以Django框架内置了form组件来验证用户提交的信息 form组件的2大功能:       1 验证(显示错误信息)       2 保留用户上次输入的信息                  -- 可以生成html标签应用: class A_Form(Form): 字段=fields.字段类型(默认参数: required=True, widget=widgets.插件(attrs={})) 常用字段:Charfield,RegexField,I

Django框架进阶

Django ORM那些相关操作 Django中ORM介绍和字段及字段参数 Cookie.Session和自定义分页 原文地址:https://www.cnblogs.com/allen-w/p/9225716.html

Linux进阶之bash编程四(内置变量)

一:基础回顾 1:文件清空 [[email protected] test]$ >log.txt 2:正常和错误重定向输出 //正常和错误都追加输出到同样地方 [[email protected] test]$ ifconfig &>>log.1 //正常输出重定向[[email protected] test]$ ifconfig >log //错误输出重定向[[email protected] test]$ ifconfig 2>log.23:命令执行控制 //休

JavaScript进阶 - 第7章 JavaScript内置对象

第7章 JavaScript内置对象 7-1 什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法:能够在对象上执行的动作.例如,表单的“提交”(Submit),时间的“获取”(getYear)等: JavaScript 提供多个内建对象,比如 String.Date.Array 等等,使用对象前先定义,如下使用数组对象:   var objectNa

[py][mx]django的cookie和session操作

这玩意可以实现7天免登录等功能. session和cookie机制原理和交互过程 交互过程 ① 客户端访问,无服务端写入的Cookie ② 服务端的Cookie写入浏览器 ③ 浏览器解析Cookie,保存至浏览器文件 ④ 客户端访问,有服务端写入的Cookie ⑤ 服务器获取 django请求中的cookie 第一次访问服务端会给一个csrf的cookie 登录完成后,默认给一个为期半个月的cookie 用于访问别的也没使用. django中cookie与session的实现原理 app默认注册

Django框架进阶5 models常用字段及参数, choices参数, 自动显示sql命令配置, orm查询优化相关, orm中的事务操作, MTV与MVC模型, 图书管理系统(图书的增删改查)

models中的常用字段 AutoField(primary_key=True) 主键   (int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列.) CharField(max_length=32)     varchar(32) IntegerField()       int BigIntergerField()           bigint DecimalField()    decimal EmailField(

Django框架进阶7 django请求生命周期流程图, django中间件, csrf跨站请求伪造, auth认证模块

django请求生命周期流程图 djang中间件 它是django的门户 只要是全局相关的功能你都应该考虑使用django中间件来帮你完成 全局用户身份校验 全局用户访问频率校验 用户访问黑名单 用户访问白名单 # 只要以后用django开发业务 设计到全局相关的功能 你就考虑用中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.Sessio