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)
快速汇总(记忆版)
-
instance:传模型对象 = 更新;不传 = 新增
-
is_valid() :执行数据校验,失败看
errors -
validated_data:校验通过的安全数据,校验后才能用
-
partial :
True= 局部更新(只改部分字段) -
set():多对多 → 覆盖原有关系
-
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 底层设计思想:
-
GenericAPIView= DRF 原生GenericAPIView(通用基础视图) -
ListModelMixin/CreateModelMixin...= DRF 五大混入类 (Mixin) -
最后组合 = 拼装出具备增删改查能力的视图
本质:抽公共代码 → 封装基类 + 功能混入 → 子类直接复用 ,避免重复写 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