Django框架基本语法(二)

Django 框架(二)

六、 请求与响应

官方文档地址:https://docs.djangoproject.com/en/4.0/ref/request-response/

1、 HttpRequest

1.1 介绍

页面被请求,Django创建一个HttpRequest对象,该对象里有请求的源数据。django会加载适当的视图,将HttpRequest作为第一个参数传递给视图函数,每个视图负责返回一个HttpResponse对象。

服务器接收到http协议的请求后,会根据报文创建HttpRequest对象视图函数的第一个参数是HttpRequest对象在django.http模块中定义了HttpRequest对象的API

1.2 接口

1.3 表单

这里默认会将文件写入相应路径,同时提交表单,推荐使用post方式提交,更加安全

index.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form表单</title>
</head>
<body>
<form action="{% url 'student:index' %}" method="post"> {% csrf_token %} <!--如果action为空,则将数据提交给当前页面,使用csrf_token离开解决跨域问题-->
    <label for="username">用户名</label>
    <input type="text" name="username" id="username" placeholder="please input your name"/>
    <label for="pwd">密码</label>
    <input type="password" name="pwd" id="pwd" placeholder="please input your password">
    <input type="submit" value="提交">
</form>
</body>
</html>

csrf跨域问题:

  • django的配置中设置了跨站请求的限制,默认禁止的状态
  • form表单发送post请求时,服务端要求客户端加上csrfmiddlewatetoken字段,该字段的值为当前会话ID加上一个密钥的散列值。
  • 防止跨域请求

解决方法:

  1. form表单后边加上{% csrf_token %},推荐使用这种方式

  2. 修改配置文件

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        # 'django.middleware.csrf.CsrfViewMiddleware',  # 把这一行注释掉,不进行视图的csrf验证,防止其他网站伪造请求进行访问	
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    

views.py

from django.shortcuts import render
from django.http import HttpResponse
import json

# Create your views here.
# path("index/", views.index, name="index")  路由地址
def index(request):
    """这里的操作只是测试,在实际中会对提交的密码和账户进行校验,成功返回首页面,失败返回登录页面"""
    if request.method == "POST":
        # 返回数据
        username = request.POST.getlist('username')  # 返回列表
        pwd = request.POST.getlist('pwd')  # 也可以通过get方法来获取,推荐使用getlist()
        resp = {'code': 200, 'username': username[0], "pwd": pwd[0]}
        return HttpResponse(json.dumps(resp), content_type="application/json")
    return render(request, "student/index.html")

总结:

  1. GET:如其名,是从服务器获取数据,不会更改服务器的状态和数据,在URL中可携带参数
  2. POST:将一定数据发送给服务器,一般都会更改服务器的数据
  3. 相对来说,POST提交数据的方式比GET安全一点
1.4 文件上传

index.html修改成

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>form表单</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data"> {% csrf_token %}
    <input type="file" name="file" multiple="multiple">  <!--可以进行多文件上传-->
    <input type="submit" value="提交">
</form>
</body>
</html>

views.py修改成

from django.shortcuts import render
from django.http import JsonResponse
from CRM.settings import MEDIA_ROOT  # 导入配置文件,在配置文件中设置了文件存储路径
# MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
from datetime import datetime
import os


# Create your views here.
# path("index/", views.index, name="index")  路由地址
def index(request):
    if request.method == "POST":
        file = request.FILES.getlist("file")  # 建议使用getlist,当然,也可以使用get方法
        day_dir_name = datetime.now().strftime("%Y%m%d")  # 定义目录名
        day_dir = os.path.join(MEDIA_ROOT, day_dir_name)  # 设置路径
        # 创建路径,存在则不创建
        if not os.path.exists(day_dir):
            os.mkdir(day_dir)
        for file in files:
            with open(f"{day_dir}/{file.name}", "wb") as f:
                for line in file:
                    f.write(line)  # 防止文件过大,进行逐行逐行写入
        return JsonResponse({"code": 200}, content_type="application/json")
    return render(request, "student/index.html")

2、 HttpResponse

2.1 常用方法

在这里插入图片描述

当进行前后端分离的时候,可以需要将我们的响应数据传递给前端页面,然后由前端页面进行渲染,可以使用类视图,我们暂时学的是前后端不分离,使用context参数进行上下文管理

同时,响应的更多方法,请到官网进行查看!

2.2 类视图
from django.views import View
from django.http import JsonResponse

# path("test/", views.ViewTest.as_view(), name="test"),  # 注册类视图的方法,这个主要用于前后端分离开发,作为后端的响应
class ViewTest(View):
    def get(self, request):
        return JsonResponse({"code": 200, "data": {"page": "1", "title": "test文档"}})  # 将我们后端的数据进行封装成JSON数据后,传递给前端进行渲染

    def post(self, request):
        return JsonResponse({"code": 200, "data": {"name": "lihua", "age": 1}})
2.3 Cookies

HTTP(超文本传输协议)是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

服务器无法区分请求是哪个客户端发送过来的,故这时候就可以使用Cookies来区分了。客户端向服务器发送请求,服务器在http协议加上请求头,通过响应,传送并保存在客户端,客户端再次访问时,就会自动带上这个cookie。

from django.http import JsonResponse, HttpResponse

# 这里我们使用类视图来演示
class ViewTest(View):
    def get(self, request):
        if not request.COOKIES.get("name"):  # 如果没有cookies,设置cookies,
            resp = HttpResponse()  # 创建一个请求
            resp.set_cookie("name", "lihua")  # 设置cookies,可以通过 max_age 设置cookies的有效时间,单位是秒
            resp["headers"] = "xxxxx"  # 设置 Response Headers
            resp.content = json.dumps({"code": 200, "msg": "登录成功"})  # 设置返回的内容
            resp.content_type="application/json"  # 设置返回数据的类型
            return resp  # 返回响应
        return JsonResponse({"code": 200})

但是这个cookies没有进行加密,容易篡改,如何解决呢?我们使用session来进行会话的加密。

3、 Session

浏览器存储cookie的方式不太安全,那有没有更好些的来存储登入状态的方式呢?

使用sesison方式,所有数据存储在服务器端,在客户端cookie中存储session_id

session基于cookierequest.session.get()

注意:

  • 使用前记得查看是否注册sessionsapp

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',  # session的app
        'django.contrib.messages',
        'django.contrib.staticfiles',
    ]
    

    . 一般来说,sessionapp的注册好的

  • 使用前也需要查看是否添加session的中间件

    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',  # session的中间件
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
  • 同时,也需要对session进行数据库的迁移

    python manage.py makemigrations sessions  # 对sessions数据库进行迁移
    python manage.py migrate sessions  # 使得迁移生效
    

    数据库中主要存储session_key,用来设置cookies

比如,登录状态的保持

def login(request):
    if request.method == "POST":
        data = request.POST
        user = data.get("username")
        pwd = data.get("password")
        if user == "kun" and pwd == "1":
            # 把用户名设置到session中去
            request.session.update({
                "user": user,  # 这个为敏感信息,故需要保存到session中
            })
            return redirect("student:index")
    return render(request, "student/login.html")

删除当前的状态:request.session.flush()

设置会话过期时间:

request.session.set_expiry(1)  # 设置过期时间为1秒

通过配置文件来配置会话过期时间:

SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得session过期,默认是False

SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session,默认修改之后才保存

SESSION_COOKIE_AGE = 12.96000  # Session的cookie失效日期,默认是2周

4、 分页器

Django中内置了分页的对象

分页功能位于django.core.paginator模块。

Paginator提供包含一些对象的列表,以及你想每一页显示几条,比如每页5条、10条、20条、100条等等,它就会为你提供访问的一系列API方法,示例如下:

>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)  # 对objects进行分页,虽然objects只是个字符串列表,但没关系,一样用。每页显示2条。

>>> p.count   # 对象个数
4
>>> p.num_pages  # 总共几页
2
>>> type(p.page_range)  # `<type 'rangeiterator'>` in Python 2.
<class 'range_iterator'>
>>> p.page_range  # 分页范围
range(1, 3)

>>> page1 = p.page(1) # 获取第一页
>>> page1
<Page 1 of 2>
>>> page1.object_list # 获取第一页的对象
['john', 'paul']

>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']
>>> page2.has_next()  # 判断是否有下一页
False
>>> page2.has_previous()# 判断是否有上一页
True
>>> page2.has_other_pages() # 判断是否有其它页
True
>>> page2.next_page_number() # 获取下一页的页码
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number() # 获取上一页的页码
1
>>> page2.start_index() # 从1开始计数的当前页的第一个对象
3
>>> page2.end_index() # 从1开始计数的当前页最后1个对象
4

>>> p.page(0)  # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3) # 访问不存在的页面
Traceback (most recent call last):
...
EmptyPage: That page contains no results

简单地说,使用Paginator分四步走:

  • 使用任何方法,获取要展示的对象列表QuerySet
  • 将对象列表和每页展示数量传递给Paginator,返回一个分页对象
  • 调用该对象的各种方法,获取各种分页信息
  • 在HTML模板中,使用上面的分页信息构建分页栏

七、 表单类

1、 普通表单

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "form.py"
__time__ = "2022/8/29 18:44"

from django.shortcuts import render
from django import forms


class RegisterForm(forms.Form):
    """创建一个普通表单"""
    username = forms.CharField(label="用户名", max_length=20)
    pwd = forms.CharField(
        label="密码",
        max_length=8,
        min_length=6,
        widget=forms.PasswordInput(attrs={
            "placeholder": "请输入6~8位的密码"  # 设置表单的一些属性,可以设置类名等
        }),  # 设置输入框类型,默认为文本输入框
        error_messages={
            "min_length": "密码长度小于六位",
            "max_length": "密码长度大于八位"
        },  # 设置报错信息
    )
    pwd_repeat = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(attrs={
            "placeholder": "请再次输入密码",
        }),
        error_messages={
            "min_length": "密码长度小于六位",
            "max_length": "密码长度大于八位"
        }  # 设置报错信息
    )
    email = forms.EmailField(required=False)  # 邮箱字段

    def clean(self):
        """"扩展校验功能,使得多个字段可以相互检验"""
        cleaned_data = super(RegisterForm, self).clean()  # 继承父类的clean方法
        # 扩展校验功能
        pwd = cleaned_data.get("pwd")
        pwd_ = cleaned_data.get("pwd_repeat")
        if pwd_ != pwd:
            msg = "两次密码不一致"
            self.add_error("pwd_repeat", msg)


# path("", form.register, name="register")  # 注册路由
def register(request):
    if request.method == "GET":
        form = RegisterForm()
    if request.method == "POST":
        data = request.POST
        form = RegisterForm(data)  # 构建一个填充好数据的对象
        if form.is_valid():
            # 判断校验是否成功,成功返回True
            username = form.cleaned_data.get("username", None)  # 从校验后的数据中,获取用户名
            print("用户名为", username)

    return render(request, "student/register.html", {
        "form": form,
    })

创建表单的参数:

  • max_length:最大长度
  • min_length:最小长度
  • widget:负责渲染网页上HTML表单的输入元素和提取提交的原始数据
  • attrs:包含渲染后的Widget将要设置的HTML属性
  • error_messages:报错信息
  • validators:验证器

可以参考我以前的博客中flask的表单验证,原理大概相同

2、 模型表单

官方文档地址:https://docs.djangoproject.com/zh-hans/4.0/topics/forms/modelforms/

使用示例:

from django.shortcuts import render
from django import forms
from django.db import models

class Student(models.Model):
    """我们创建的模型类"""
    name = models.CharField("姓名", max_length=20, )  # verbose_name 用来设置字段前边的标签文字
    age = models.SmallIntegerField()
    SEX_CHOICE = (
        [0, "女"],
        [1, "男"]
    )
    sex = models.SmallIntegerField(choices=SEX_CHOICE, default=1)  # 其生成字段后,是一个下拉框
    qq = models.CharField(max_length=20, unique=True, error_messages={
        "unique": "qq号码重复"  # 设置报错信息
    })
    phone = models.CharField(max_length=20, unique=True)
    c_time = models.DateTimeField("创建时间", auto_now_add=True)
    e_time = models.DateTimeField("修改时间", auto_now=True)
    is_delete = models.BooleanField(default=False)  # 逻辑删除,False代表没删除
    grade = models.ForeignKey("Grade", on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return f"{self.name}-{self.age}"


class StudentForm(forms.ModelForm):
    class Meta:
        """在这里指定要映射的模型类"""
        model = Student  # 指定我们创建的学生模型
        # fields = "__all__"  # 所有字段都进行展示
        exclude = ["is_delete"]  # 指定不需要展示的字段
        widgets = {
            "sex": forms.RadioSelect(attrs={})  # 设置字段类型
        }
    def clean_qq(self):
        """对单个字段进行校验"""
        data = self.cleaned_data  # 校验后的数据,再对该字段进行校验
        if not data.isdigit():
            self.add_error("qq", "你输入的qq号码有问题")
        return data  # 要记得将数据返回


def register(request):
    if request.method == "GET":
        form = StudentForm()
    if request.method == "POST":
        data = request.POST
        student = None  # 获取到学生对象
        form = StudentForm(data, instance=student)  # 构建一个填充好数据的对象,instance参数,覆盖原来的数据
        if form.is_valid():
            # 判断校验是否成功,成功返回True
            username = form.cleaned_data.get("username", None)  # 从校验后的数据中,获取用户名
            print("用户名为", username)

    return render(request, "student/register.html", {
        "form": form,
    })

表单属性:

from student.form import *
forms = StudentForm() 
for form in forms:
	print(form.label)  # 获取字段对应的标签
    print(form.id_for_lable)  # 获取标签对应的id
    form.as_widget(attrs={
        "class": "class_str"
    })  # 使用这个方法,给该字段增加样式、属性
    print(form.errors)  # 获取报错信息
    print(form.value)  # 获取该字段的值
# 这些属性可以用来自定义我我们的表单,使其个性化

八、 中间件

django中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量**,**其中每一个元素就是一个中间件

官方网站地址:https://docs.djangoproject.com/zh-hans/4.1/topics/http/middleware/

1、 创建中间件

顾名思义:请求送入之前和响应送出之前对请求和响应进行处理的组件

中间件的命名和存储是可以任意的,只要是可以导入就行

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "middleware.py"
__time__ = "2022/8/30 19:24"

"""使用装饰器作为中间件"""


# 函数中间件
def simple_middleware(get_response):
    """get_response参数名不可以修改"""
	print("初始化")
    def middleware(request):
        print("视图函数调用之前,进行检验")
        response = get_response(request)  # 视图函数执行
        print("视图函数调用之后,进行检验")
        return response

    return middleware


# 类中间件
class SimpleMiddleware:
    """也可以使用类来作为装饰器"""
	print("初始化")
    def __init__(self, get_response):
        self.get_response = get_response
        print("初始化")

    def __call__(self, request):
    	print("请求前")
        if "chrome" not in request.META.get("HTTP_USER_AGENT").lower():
            "如果不是使用Chrome浏览器,则拒绝访问"
            return HttpResponseForbidden()
        response = self.get_response(request)
        print(response)
        return response  # 将响应返回

2、 注册中间件

我们需要在配置文件中,注册我们自定义的中间件

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',
    'student.middleware.SimpleMiddleware',  # 注册类中间件
    'student.middleware.simple_middleware'  # 注册函数中间件
]

九、 上下文处理器

1、 创建

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
__author__ = "A.L.Kun"
__file__ = "customer_context.py"
__time__ = "2022/8/30 20:08"


def my_name(request):
    return {
        "name": "fei"  # 将name对应的值添加到全局变量中,这个变量可以通过request中的数据进行获取
    }

2、 注册

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'student.customer_context.my_name',  # 注册创建的上下文处理器
            ],
        },
    },
]

所有页面共用的变量,如果同时存在,优先使用context中的变量

十、 管理系统

1、 配置

要求

  1. app注册
  2. 中间件注册
  3. 路径配置

根据路径访问管理员站点:http://127.0.0.1:1236/admin/

创建管理员账号:在项目根目录下运行shell

python manage.py createsuperuser

根据要求来创建超级用户

2、 管理模型

studentapp中,来注册我们的模型,使得我们可以通过管理员用户来修改:

Django提供了admin.ModelAdmin

通过定义ModelAdmin的子类,来定义模型在Admin界面的显示方式

  • 列表页属性

    list_display:显示字段,可以点击列头进行排序

    list_filter:过滤字段,过滤框会出现在右侧

    search_fields:搜索字段,搜索框会出现在上侧

    list_per_page:分页,分页框会出现在下侧

  • 添加、修改页属性

    fields:属性的先后顺序

    fieldsets:属性分组

注意:上面两个属性,二者选一

from django.contrib import admin
from .models import Student, StudentDetail


# Register your models here.

# 自定义
class StudentAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'sex', 'age', 'qq', 'phone']  # 指定显示字段
    list_display_links = ['name', 'sex']  # 指定跳转详情字段
    search_fields = ['name', 'qq', 'phone']  # 自定义搜索字段
    list_filter = ['sex']  # 过滤
    list_per_page = 5  # 每页显示数量

    # fields = ['age'] # 只允许修改的字段,和字段分组设置二选一
    # exclude = []  # 排除字段
    # 分组设置
    fieldsets = [
        (None, {'fields': ['name', 'sex']}),
        ('详细信息', {'fields': ['age', 'qq', 'phone']}),
        ('设置', {'fields': ['is_delete']}),
    ]


admin.site.register(Student, StudentAdmin)  # 注册自定义模型
admin.site.register(StudentDetail)  # 注册模型

3、 auth

3.1 数据表

auth系统中的数据表

UserUser是auth模块中维护用户信息的关系模式(继承了models.Model), 数据库中该表被命名为auth_user.

GroupUser对象中有一个名为groups的多对多字段, 多对多关系由auth_user_groups数据表维护。Group对象可以通过user_set反向查询用户组中的用户。

PermissionDjangoauth系统提供了模型级的权限控制, 即可以检查用户是否对某个数据表拥有增(add), 改(change), 删(delete)权限。

3.2 验证系统

配置文件讲解:

INSTALLED_APPS = [
    'django.contrib.admin',  # 管理系统
    'django.contrib.auth',  # 权限系统
    'django.contrib.contenttypes',  # 把权限和模型关联起来
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'student'
]

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. 授权:决定用户做什么

当前登录用户,是一个user对象,或者是一个AnonymousUser匿名用户实例,它会被存储在模板变量{{ user }}

登录功能的实现:

from django.contrib.auth import authenticate  # 对用户进行校验
from django.contrib.auth import login as login_  # 进行登录,反正重名

# path("", views.login, name="login")
def login(request):
    # 判断是否登录
    if request.user.is_authenticated:  # 匿名用户返回false
        return redirect("student:index")

    if request.method == "POST":
        data = request.POST
        user = data.get("username")
        pwd = data.get("password")
        usr = authenticate(username=user, password=pwd)  # 如果验证失败,返回空;验证正确,返回一个用户对象
        if usr:  # 如果验证正确
            # 把用户名设置到session中去
            login_(request, usr)  # 将请求与用户关联起来
            return redirect("student:index")
    return render(request, "student/login.html")

# path("/", views.login, name="login")
def login_out(request):
    logout(request)  # 登出功能

登录验证:

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator  # 将函数装饰器,转换为方法装饰器
from django.views import View

# Create your views here.
@method_decorator(login_required)  # 进行登录验证
class Register(View):
    def get(self, request):
        return "正在注册"

@login_required  # 对是否登录进行验证,如果没有登录,跳转到登录页面
def index(request):
    students = None  # 声明学生为空,查看post请求是否得到数据
    name = request.session.get("user", "游客")
    search = ''  # 默认搜索内容为空
    if request.method == "POST":
        search = request.POST.get("search", "").strip()  # 获取到数据
        if search:  # 如果search有值,则筛选,否则返回全部数据
            if search.isdigit():
                students = Student.objects.filter(Q(qq=search) | Q(phone=search), is_delete=False)
            else:
                students = Student.objects.filter(name=search, is_delete=False)
    if not students:
        students = Student.objects.filter(is_delete=False)

    section = "学生列表"
    return render(request, "student/index.html", context={
        "section": section,
        "students": students,
        "search_val": search,
        "name": name,
    })

登录页面的路径在配置文件中配置:

from django.urls import reverse_lazy

LOGIN_URL = reverse_lazy("student:login")  # 懒加载

登录常用接口

create_user 创建用户   
authenticate 验证登录
login 记住用户的登录状态
logout 退出登录
is_authenticated 判断用户是否登录
login_required 判断用户是否登录的装饰器
permission_required 权限验证装饰器
3.3 User模型

User模型常用属性和方法:

User对象有两个多对多字段:groupsuser_permissionsUser对象可以通过他们访问管理对象

3.4 Group模型
# user 为登录用户
# 组操作
user.groups.add(g2)  # 将用户添加到g2组
user.groups.clear()  # 清空用户添加的组
user.groups.set([g1, g2])  # 将用户添加到g1, g2组
user.groups.remove(g1, g2)  # 将用户从g1, g2组中移除

g1.user_set.add()  # 通过反向代理来把用户添加到组中
3.5 Permission模型
# user 为登录用户
# 权限操作
user.user_permissions.set([25,26,27,28])	# 设置
user.user_permissions.remove(25,28)  # 移除
user.user_permissions.add(25,28)  # 添加
user.user_permissions.clear()  # 清空,对应功能的id
# 对组进行权限操作
gl.permissions.add(permission)  # 添加某个权限

# 查看用户是否有某个app下某个模型的某个操作功能(增add删delete改change查view)
user.has_perm('student.view_student')  # app.add_模型

权限会被存储在模板变量{{ perms }}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SteveKenny

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值