Django 框架 深度学习 第二课程

Django 框架高级

路由中尽可能以名词为主,不要出现太多动词

useradd 模块 + 功能

adduser 功能 + 模块

get/post/put/delete

user get 用户列表

user post---- 请求体参数 用户添加

user post 用户列表

user/1 delete 用户删除

user put--- 请求体 用户修改

上述请求方式,是网站访问过程中的一种设计风格,RESTFULL 风格

Django + RESTFULL ======== Django Rest Framework (DRF)

Django Rest Framework(简称 DRF

它就是 Django 的「接口专用增强包」

专门用来在 Django 里快速、规范、轻松地写出 RESTful API 接口,给前端、小程序、APP 提供数据。


1. 它到底是干嘛的?

你用原生 Django 只能做:

  • 网页渲染(返回 HTML)

  • 表单提交

但你要做前后端分离项目(前端 Vue/React/ 小程序,后端只返回 JSON),原生 Django 很麻烦。

DRF 就是解决这个问题的:

让你用极少代码,直接生成一套标准 RESTful 增删改查接口


2. 用 DRF 能得到什么?(最实用的 4 个功能)

① 自动生成 RESTful 接口(你最关心的)

写几行代码,直接拥有:

  • GET 获取列表

  • POST 新增

  • PUT 修改

  • DELETE 删除

URL 全是名词,不带动词,完全符合 RESTful


② 自动序列化(模型 ↔ JSON 自动转换)

不用你手动拼 JSON,DRF 帮你:

  • 把数据库数据 → JSON 给前端

  • 把前端传的 JSON → 存进数据库


③ 自带接口调试页面(超级好用)

运行项目后,直接在浏览器访问接口,就能:

  • 看数据

  • 发 POST/PUT/DELETE 请求测试

    不用装 Postman!


④ 内置权限、分页、过滤、认证

开箱即用:

  • 登录才能访问

  • 接口分页

  • 搜索过滤

  • 接口限流


3. 用一句话总结它的地位

Django = 做网站 Django Rest Framework = 用 Django 做 API 接口

接口 = 后端给前端提供的数据通道
API(应用程序编程接口) 长什么样?

为一个地址

  • 不是页面

  • 不是图片

  • 就是 一串数据(JSON)

示例:

javascript 复制代码
{
  "code": 200,
  "msg": "成功",
  "data": {
    "username": "小明",
    "email": "test@qq.com"
  }
}

4. 最简单对比(一看就懂)

不用 DRF(原生 Django 写接口)

  • 代码多

  • 要自己处理 JSON

  • 要自己处理增删改查

  • 不规范

用 DRF

  • 代码极少

  • 自动 JSON

  • 自动增删改查

  • 标准 RESTful

  • 自带调试页面


5. 你之前学的 RESTful,DRF 就是落地工具

你前面记的规则:

  • URL 用名词

  • 动作由 GET/POST/PUT/DELETE 决定

  • user/ 获取列表

  • user/1 删除用户

这些规则,DRF 全部自动帮你实现!


总结

Django Rest Framework = Django 的 API 开发神器

专门帮你快速写出规范、好用、符合 RESTful 风格的后端接口

数据序列化

第一步 手动拼接
python 复制代码
from django.views import View
from django.http import JsonResponse
from .models import Book, Press  # 确保你的模型在 models.py 里定义好了
​
class BookView(View):
    def get(self, request):
        # 1. 从 Book 表查询数据,指定字段
        bookresult = list(
            Book.objects.values(
                "id", "bookname", "bookprice", 
                "bookauthor", "pressdate", "category", "press"
            )
        )
   result = []
    # 2. 遍历每一本书,把外键 press 对应的出版社信息替换成字典
    for book in bookresult:
        book["press"] = {
            "id": book["press"],
            "pressname":                 Press.objects.get(id=book["press"]).pressname,
            "pressaddress": Press.objects.get(id=book["press"]).pressaddress
        }
        result.append(book)
​
    # 3. 返回 JSON 数据给前端
    return JsonResponse(result, safe=False)
第二步 DRF自动拼接 serializers
python 复制代码
from  django.core import serializers
def get(self,request):
    book == ....
    data = serializers.serializer('json',book)
    return ...
    
#这种方法还实现单一对象 如果有一对多和多对多 无法进行序列化
方式三:DRF序列化
第一步:安装DRF

pip install djangorestframework

第二步:创建DRF的序列化器
python 复制代码
class PressSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    pressname = serializers.CharField(max_length=30)
    pressaddress = serializers.CharField(max_length=50)
    
class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    bookname = serializers.CharField(max_length=50)
    bookprice = serializers.FloatField
    bookauthor = serializers.CharField(max_length=50)
    pressdate = serializers.DateField()
    # 语言
    category = serializers.IntegerField(choices=((1, "汉语"), (2, "英语"), (3, "法语"), (4, "日语")))
    # 多对一
    press = PressSerializer()
第三步:创建DRF的视图层View
python 复制代码
from rest_framework.response import Response
from rest_framework.views import APIView
​
from app01.models import *
from app01.MySerializers import *
​
class BookView(APIView):
    
    def get(self,reqeust):
        bookresult = Book.objects.all()
        # 将查询到的结果进行DRF序列化
        bookSerializer = BookSerializer(bookresult,many=True)
        # 返回
        return Response(bookSerializer.data)
第四步:在settings.py文件中,对drf做配置
python 复制代码
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    'app01.apps.App01Config',
    "rest_framework"
]
第五步:启动服务,访问路由

数据反序列化

实现数据添加操作

第一步:考虑添加过程中的数据提交格式

python 复制代码
{
    "bookname": "鹿鼎记",
    "bookauthor": "金庸",
    "bookprice":50,
    "pressdate": "2026-04-28",
    "category2": 2,
    "press2": 1,
    "booktype2": [1,3]
}

第二步:在序列化器中追加特殊的反序列化字段(标记好只读和只写)和ID字段

python 复制代码
class BookSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=False, read_only=True)
    bookname = serializers.CharField(max_length=50)
    bookprice = serializers.DecimalField(max_digits=5, decimal_places=2)
    bookauthor = serializers.CharField(max_length=50)
    pressdate = serializers.DateField()
​
    # 只读:返回给前端看的
    category = serializers.CharField(source='get_category_display', read_only=True)
    press = PressSerializers(read_only=True)
    booktype = BookTypeSerializers(many=True, read_only=True)
​
    # 只写:前端传参用
    category2 = serializers.CharField(write_only=True)
    press2 = serializers.IntegerField(write_only=True)
    booktype2 = serializers.ListField(
        write_only=True
    )

第三步:在视图逻辑层,接收提交数据与封装序列化器对象并进行验证

python 复制代码
def post(self,request):
    # 接收参数
    book_obj = request.data
    # 调用orm  封装序列化器
    book_ser = BookSerializer(data=book_obj)
    # 需要对封装完成以后得序列化对象做验证
    # 如果得到Ture,则验证通过;如果是False,则需要检查序列化字段与反序列化字段
    print(book_ser.is_valid())

第四步:调用save方法执行添加操作

python 复制代码
def post(self,request):
    # 接收参数
    book_obj = request.data
    # 调用orm  序列化器
    book_ser = BookSerializer(data=book_obj)
    # 需要对封装完成以后得序列化对象做验证
    if book_ser.is_valid():
        book_ser.save()
        return Response("添加成功")
    # 返回序列化数据
    return Response("添加失败")

第五步:在序列化器中重写create方法,调用底层ORM,如果没有重写create,则运行报错

python 复制代码
def create(self, validated_data):
    # 2. 创建书籍对象
    book = Book.objects.create(
        bookname=validated_data.get('bookname'),
        bookprice=validated_data.get('bookprice'),
        bookauthor=validated_data.get('bookauthor'),
        pressdate=validated_data.get('pressdate'),
        category=validated_data["category2"],
        press_id=validated_data['press2'],
    )
    # 3. 处理多对多:书籍类型
    book.booktype.add(*validated_data['booktype2'])
​
    return book

第六步:测试添加效果

实现数据修改操作

第一步 :配置URL

复制代码
urlpatterns = [
    path('book/',app.views.BookView.as_view()),
    path('book/<int:id>/', app.views.BookView2.as_view()),
​
]

第二部 在视图逻辑层,接收提交数据与封装序列化器对象并进行验证

python 复制代码
class BookView2(APIView):
    def get(self,request,id):
        book = Book.objects.get(id=id)
        book = BookSerializer(book)
        return Response(book.data)
​
    def delete(self,request,id):
        Book.objects.get(id=id).delete()
        return Response({"msg":"删除成功"})
​
    def put(self,request,id):
        book = Book.objects.get(id=id)
        ser = BookSerializer(book,data=request.data,partial=True) # 局部修改
        if ser.is_valid():
            ser.save()
            return Response({"msg":"修改成功"})
        return Response(ser.errors)

第三部 增加的代码实现修改操作 重写 updata

python 复制代码
def update(self, instance, validated_data):
    instance.bookname = validated_data.get('bookname', instance.bookname)
    instance.bookprice = validated_data.get('bookprice', instance.bookprice)
    instance.bookauthor = validated_data.get('bookauthor', instance.bookauthor)
    instance.pressdate = validated_data.get('pressdate', instance.pressdate)
    instance.category = validated_data.get('category2', instance.get_category_display())
    instance.press_id = validated_data.get('press2', instance.press_id)
​
    if validated_data.get('booktype2'):
        instance.booktype.set(validated_data['booktype2'])
    instance.save()
​
    return instance

第 四步 测试效果

补充

DRF 核心参数 / 方法通俗讲解

结合 ** 序列化器 (Serializer)** 日常使用场景,逐个讲清,附用法示例。

一、instance

作用

接收数据库已有模型对象 ,用于更新 / 修改数据

  • 不传 / 传 None:代表新增数据

  • 传模型实例对象:代表更新已有数据


二、data & validated_data

1. data

原始传入的前端请求数据 (字典),未校验,可能含非法字段、格式错误。

  • 来源:request.data、手动传入的字典
2. validated_data

校验通过后的干净数据(字典)。

  • 必须先执行 is_valid() 校验成功后才能使用

  • 自动过滤非法字段、完成类型转换、执行字段校验规则

  • create() / update() 方法时**必用*

复制代码
ser = UserSerializer(data={"age": "20"})
ser.is_valid()  # 先校验
print(ser.data)          # 原始数据
print(ser.validated_data) # 校验后合规数据,age 已转为数字

三、is_valid() 方法

作用

执行全字段校验(类型、长度、正则、自定义校验器等)。

  • 返回值:True= 校验通过;False= 校验失败

  • 校验失败可通过 ser.errors 查看错误信息

必写规则

使用 validated_data 前,必须先调用 is_valid()

python 复制代码
ser = UserSerializer(data={"age": 200})
if ser.is_valid():
    ser.save()
else:
    print(ser.errors)  # 输出错误提示
补充参数:raise_exception=True

校验失败直接抛出异常,DRF 会自动返回 400 响应,接口常用:

复制代码
ser.is_valid(raise_exception=True)

四、partial 参数

作用

局部更新开关 ,布尔值,搭配 instance 更新使用。

  • partial=False(默认):全量更新,所有必填字段必须传,缺字段直接校验失败

  • partial=True局部更新,只传需要修改的字段,其他字段可不传

场景

只改用户名,不改其他必填字段:

复制代码
user = User.objects.get(id=1)
# partial=True 局部更新
ser = UserSerializer(instance=user, data={"name":"新名字"}, partial=True)
ser.is_valid()
ser.save()

总结:新增不用 partial部分字段更新必须加 partial=True


五、add()set()(针对多对多字段

DRF/ORM 中专门操作 ManyToManyField 多对多关系的方法,作用是关联 / 解绑关联数据

前置说明

假设有模型:文章 (Article) 和 标签 (Tag),多对多关联。

1. set(可迭代对象)

覆盖式设置:清空原有所有关联,再重新绑定新数据。

  • []:直接清空所有关联
python 复制代码
article = Article.objects.get(id=1)
# 把文章标签 全部替换 为 tag1、tag2
article.tags.set([tag1, tag2])
2. add(对象/主键)

追加式添加不删除原有关联,只新增关联关系。

  • 可传模型对象、主键 id、多个参
python 复制代码
# 在原有标签基础上,额外再加一个 tag3
article.tags.add(tag3)
# 也可以传id
article.tags.add(3)
补充对应解绑:remove()
复制代码
# 移除指定关联,保留其他
article.tags.remove(tag3)

快速汇总(记忆版)
  1. instance:传模型对象 = 更新;不传 = 新增

  2. is_valid() :执行数据校验,失败看 errors

  3. validated_data:校验通过的安全数据,校验后才能用

  4. partialTrue= 局部更新(只改部分字段)

  5. set():多对多 → 覆盖原有关系

  6. add():多对多 → 追加新关系,保留原有

DRF 2.0 版本

python 复制代码
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'
        extra_kwargs = {
            "press": {"write_only": True},
            "booktype": {"write_only": True},
            "category": {"write_only": True},
        }
        # depth = 1  # 深度查询.
    category_display = serializers.SerializerMethodField(read_only=True)
    press_display = serializers.SerializerMethodField(read_only=True)
    booktype_display = serializers.SerializerMethodField(read_only=True)
​
    def get_category_display(self, obj):
        return obj.get_category_display()
    def get_press_display(self, obj):
        return {"id":obj.press.id,"pressname":obj.press.pressname}
    def get_booktype_display(self, obj):
        return [{"id":i.id,"typename":i.typename} for i in obj.booktype.all()]

什么是序列化什么是反序列化?

一、核心定义

1. 序列化(Serialize)

把内存中运行的对象 / 数据结构,转换成可存储、可网络传输的字节串 / 字符串格式。 内存中的对象不能直接存硬盘、发网络,序列化就是做「打包」。

2. 反序列化(Deserialize)

把字节串 / 字符串还原回程序内存里原生对象 / 数据结构。相当于「解包」,恢复成程序能直接调用的变量、对象。

DRF中的1.0 以及 2.0 的区别

特性 APIView ModelViewSet
定位 DRF 视图体系的基础父类,所有视图的 "根" 基于 ViewSet + ModelMixin封装类,专门给模型 CRUD 用
CRUD 方法 完全手动写:get() / post() / put() / delete() 自动提供:list() / retrieve() / create() / update() / destroy()
路由配置 需手动为每个方法绑定 URL 配合 DefaultRouter 自动生成 5 个标准接口路由
自定义程度 极高,所有逻辑自己写 中等,可通过重写方法、权限类、过滤类扩展
适用场景 非模型接口、复杂业务逻辑、非标准请求 模型的标准 CRUD 接口、快速开发后台接口

DRF2.0 高级

在DRF的基础上 进行封装

python 复制代码
# # 封装通用模块
# #通用模块
# class GenericAPIView(APIView):   公共父类
#     queryset = None
#     serializer_class = None
#
#     def get_queryset(self):
#         return self.queryset.all()
#
#     def get_serializer_class(self,*args,**kwargs):
#         return self.serializer_class(*args,**kwargs)
#
# #通用查询所有模块
# class ListModelMixin(object):
#     def list(self,request):
#         queryset = self.get_queryset()
#         ser_obj = self.get_serializer_class(queryset,many=True)
#         return Response(ser_obj.data)
#
# #通用添加模块
# class CreateModelMixin(object):
#     def create(self,request):
#         ser_obj = self.get_serializer_class(data=request.data)
#         if ser_obj.is_valid():
#             ser_obj.save()
#             return Response(ser_obj.validated_data)
#         return Response(ser_obj.errors)
#
# #通用查询某一个模块
# class RetrieveModelMixin(object):
#     def retrieve(self,request,id):
#         queryset = self.get_queryset().get(id=id)
#         # 序列化
#         ser_obj = self.get_serializer_class(queryset)
#
#         return Response(ser_obj.data)
#
# #通用删除某一个模块
# class DestroyModelMixin(object):
#     def destroy(self,request,id):
#         queryset = self.get_queryset().get(id=id)
#         if not queryset:
#             return Response("对象不存在")
#         # 序列化
#         queryset.delete()
#         return Response("删除成功")
#
# #通用修改某一个模块
# class UpdateModelMixin(object):
#     def update(self,request,id):
#         queryset = self.get_queryset().get(id=id)
#         ser_obj = self.get_serializer_class(instance=queryset, data=request.data, partial=True)
#         if ser_obj.is_valid():
#             # 调用orm执行修改
#             ser_obj.save()
#             return Response(ser_obj.validated_data)
#         return Response(ser_obj.errors)
#
# class ListCreateApiView(GenericAPIView,ListModelMixin,CreateModelMixin):
#     pass
#
# class RetrieveDestroyUpdateApiView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin,UpdateModelMixin):
#     pass
#
# class BookView(ListCreateApiView):
#     #提前准备查询数据与序列化器
#     queryset = Book.objects.all()
#     serializer_class = BookSerializer
#
#     def get(self, request):
#         return self.list(request)
#
#     def post(self, request):
#         return self.create(request)
#
# class BookEditView(RetrieveDestroyUpdateApiView):
#     queryset = Book.objects.all()
#     serializer_class = BookSerializer
#     def get(self, request, id):
#         return self.retrieve(request,id)
#
#     def put(self, request, id):
#         return self.update(request,id)
#
#     def delete(self, request, id):
#         return self.destory(request,id)
#
# class PressView(ListCreateApiView):
#     queryset = Press.objects.all()
#     serializer_class = PressSerializer
#
#     def get(self,request):
#         return self.list(request)
#
#     def post(self,request):
#         return self.create(request)
#
# class BookTypeView(ListCreateApiView):
#     queryset = BookType.objects.all()
#     serializer_class = BookTypeSerializer
#     def get(self,request):
#         return self.list(request)
#
# class PressView(APIView):
#     def get(self,request):
#         presslist = Press.objects.all()
#         serializer = PressSerializer(presslist, many=True)
#         return Response(serializer.data)
# class BookView(APIView):
#
#     def get(self,reqeust):
#         bookresult = Book.objects.all()
#         # 将查询到的结果进行DRF序列化
#         bookSerializer = BookSerializer(bookresult,many=True)
#         # 返回
#         return Response(bookSerializer.data)
#
#     """
#     {
#         "bookname": "鹿鼎记",
#         "bookauthor": "金庸",
#         "bookprice":50,
#         "pressdate": "2026-04-28",
#         "category2": 2,
#         "press2": 1,
#         "booktype2": [1,3]
#     }
#     """
#     def post(self,request):
#         # 接收参数
#         book_obj = request.data
#         # 调用orm  序列化器
#         book_ser = BookSerializer(data=book_obj)
#         # 需要对封装完成以后得序列化对象做验证
#         if book_ser.is_valid():
#             book_ser.save()
#             return Response("添加成功")
#         # 返回序列化数据
#         return Response("添加失败")
# class BookEditView(APIView):
#     def get(self,request,id):
#         book = Book.objects.get(id=id)
#         # 将查询到的结果进行DRF序列化
#         bookSerializer = BookSerializer(book)
#         # 返回
#         return Response(bookSerializer.data)
#
#     def delete(self,request,id):
#         book = Book.objects.get(id=id)
#         book.delete()
#         # 返回
#         return Response("删除成功")
#
#     def put(self, request, id):
#         # 得到要修改的数据库中的详细对象信息
#         book = Book.objects.get(id=id)
#
#         # instance:原始数据  data:要修改的数据   partial:局部修改
#         book_ser = BookSerializer(instance=book,data=request.data,partial=True)
#         print(book_ser.is_valid())
#         if book_ser.is_valid():
#             book_ser.save()
#             return Response("修改成功")

用这种方式可以减少好多类的创建以及 减少代码冗余

一、整体思路总结

你手写的这套代码,完全复刻了 DRF 底层设计思想

  1. GenericAPIView = DRF 原生 GenericAPIView(通用基础视图)

  2. ListModelMixin/CreateModelMixin... = DRF 五大混入类 (Mixin)

  3. 最后组合 = 拼装出具备增删改查能力的视图

本质:抽公共代码 → 封装基类 + 功能混入 → 子类直接复用 ,避免重复写 get/post/序列化/查询 逻辑。

DRF 3.0 版本

重写 URL 方法可以直接填充为 五中url 不用自己定义

python 复制代码
from rest_framework.routers import DefaultRouter
from app.views import BookView
​
router = DefaultRouter()
# 格式:register(路由前缀, 视图类, basename=唯一标识)
router.register('book', BookView, basename='book1')
# router.register('book2', BookView2, basename='book2')
​
urlpatterns = []
urlpatterns += router.urls
​
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

在 views 里面的实现 为直接继承类 不用自己在定义方法

DRF3.0版本-View

view层是继承APIView还是继承ModelViewSet?

复制代码
结论先行:
​
    简单单接口、定制化逻辑、非标准 CRUD → 用 APIView(基础视图类,自由度最高)
    标准列表 / 详情 / 增删改查全套 CRUD、配合路由自动生成 → 用 ModelViewSet(视图集,开发效率最高)
​
一、两者核心区别
1. APIView(基础视图)
DRF 最底层视图,基于 Django 原生 View 扩展,一个类对应一个接口地址。
​
    按请求方法拆分:get() / post() / put() / delete() 等
    手动写路由、手动控制逻辑,灵活度拉满
    适合:单一场景接口、复杂业务逻辑、非标准 CRUD、自定义权限 / 限流 / 响应
    
2. ModelViewSet(视图集)
封装好的全套 CRUD 视图集,继承自 ViewSet,一个类对应一组接口。
默认自动实现 5 个标准动作:
list(查列表)、retrieve(查单个)、create(新增)、update(全改)、destroy(删除)
​
    配合 DRF 路由器(DefaultRouter/SimpleRouter)自动生成路由,不用手写多条路由
    代码极简,只需要配置 queryset 和 serializer_class
    适合:标准数据表 CRUD 接口、后台管理、常规业务接口
    
二、如何选型(场景对照)
优先用 APIView
​
    接口不是标准 CRUD(如登录、验证码、文件上传、统计接口、复杂查询)
    每个接口逻辑差异大,需要深度定制请求 / 响应 / 流程
    只需要单个接口,不需要整套增删改查
    习惯 Django 原生视图写法,追求细粒度控制
​
优先用 ModelViewSet
​
    对一张数据表做完整 增删改查
    后台管理、常规业务接口,逻辑通用无特殊定制
    想少写路由、少写重复代码,快速开发
​
三、补充衍生类(常用过渡选择)
如果介于两者之间,还有折中方案:
​
    GenericAPIView + 混入类
    比 APIView 少写重复代码,比 ViewSet 更灵活,适合部分 CRUD。
    ReadOnlyModelViewSet
    只提供查询(列表 + 详情),禁用增删改,纯只读接口首选。
​
四、一句话总结
​
    追求灵活、定制、单接口 → APIView
    追求高效、标准 CRUD、自动路由 → ModelViewSet
​
日常开发中:后台管理 / 标准数据表优先 ModelViewSet;前端业务接口、特殊功能接口优先 APIView。
分页类型 核心配置 请求示例 核心特点 适用场景
页码分页PageNumberPagination page_size:默认每页条数page_query_param:页码参数名page_size_query_param:动态调整每页条数 /list?page=2&size=3 支持直接跳页,使用直观;数据量大时性能下降 传统分页列表、需要跳页的场景
偏移分页LimitOffsetPagination default_limit:默认每页条数limit_query_param:条数参数名offset_query_param:偏移量参数名 /list?offset=3&limit=3 无页码概念,实现简单;offset 越大查询越慢 数据量较小的简单列表
游标分页CursorPagination page_size:每页条数cursor_query_param:游标参数名ordering:必填排序字段 /list?cursor=xxx 依靠游标定位,只能上下翻页、不能跳页;大数据量性能最优,不易漏 / 重数据 海量数据、无限滚动、信息流、聊天记录

认证机制

前后端分离开发中,如何判断访问的路由是否合理?(是否正常登录)Token认证

python 复制代码
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
​
from app01.models import User
​
​
class MyAuth(BaseAuthentication):
    def authenticate(self, request):
​
        print(request.headers)
​
        # 判断是否有token  url  ?thoken=706c5ed1124b4191b6f8ec786b3499ae
        token = request.query_params.get('token')
        if not token:
            # 没有登录
            raise AuthenticationFailed('您还没有登录!')
        # 用户携带token,但是真假不确定
        userobj = User.objects.filter(token=token).first()
        if not userobj:
            raise AuthenticationFailed('登录信息有误,请重新登录!')
        return userobj,token

授权机制

授权机制

python 复制代码
$.ajax({
    url:"http://localhost:8000/app01/user/",
    type:"delete",
    data:{"id":1},
    headers:{"Authorization":"Bearer "+loginuser.token},
    success:funxxxxx
})
class MyPer():
    message = "您没有管理员权限!"
    def has_permission(self,request,view):
        print(request.user)
        userobj = request.user
        print(userobj)
        if userobj.type == 1:
            return True
        return False

限流机制

应用场景!!

python 复制代码
from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
​
    scope = "mytime"
​
    def get_cache_key(self, request, view):
        return self.get_ident(request)
        
# setting.py文件中配置
REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_RATES":{"mytime":"3/m"}
}
class UserView(APIView):
​
    # 认证组件
    authentication_classes = [MyAuth]
    # 授权组件
    permission_classes = [MyPer]
    # 限流组件
    throttle_classes = [MyThrottle]
​
    def get(self,request):
        print("用户删除")
        return Response("用户删除成功")

分页机制

python 复制代码
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
class MyPage(PageNumberPagination):
    page_size = 3   #每页显示3条
    page_query_param = "page"  #下一页  user?page=2
    page_size_query_param = "size"  #下一页显示多少条    user?page=2&size=3
​
class MyLimit(LimitOffsetPagination):
    default_limit = 3
​
class MyCursor(CursorPagination):
    cursor_query_param = "cursor"
    page_size = 3
    ordering = "-id"
​
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
相关推荐
Dust-Chasing1 小时前
Claude Code源码剖析 - ShellTool与真实动作
人工智能·python·ai
仙俊红1 小时前
Java JUC:CompletableFuture 详解,多个任务并行执行并等待全部完成
java·python·spring
学习3人组1 小时前
Python 评论朴素贝叶斯文本情感分析示例
人工智能·python·机器学习
用户337922545681 小时前
A2A Python SDK 源码架构解读:一个请求是如何被处理的
python
2401_885665191 小时前
从零搭建卷积神经网络:基于PyTorch实现MNIST手写数字分类
pytorch·python·神经网络·算法·机器学习·分类·cnn
SilentSamsara2 小时前
MLflow 实验追踪与模型注册:从实验到生产的可复现工作流
开发语言·人工智能·pytorch·python·青少年编程
曲幽2 小时前
写爬虫时用了代理还被封?Python 代理的那些隐藏坑,我替你踩明白了
python·http·https·proxy·socks·requests·socks5·proxies
装不满的克莱因瓶2 小时前
掌握多头自注意力机制(Multi-Head Self-Attention)——Transformer 强大表达能力的核心来源
人工智能·python·深度学习·数学·ai·transformer
我登哥MVP2 小时前
SpringCloud 核心组件解析:服务注册与发现
java·spring boot·后端·spring·spring cloud·java-ee·maven