文章目录
0. 准备环境
* 1. 创建项目
* 2. 注册rest_framework
INSTALLED_APPS = [
...
'rest_framework'
]
* 3. 创建表三张表
from django.db import models
# Create your models here.
# 用户表
class User(models.Model):
# 用户名称
username = models.CharField(max_length=32)
# 用户密码
password = models.CharField(max_length=32)
# 身份标识
identity = models.IntegerField(choices=((1, '小米1'), (2, '小米2'), (3, '小米3')))
# token表
class Token(models.Model):
# token值
value = models.CharField(max_length=64)
# 外键管理用户viands
user = models.OneToOneField(to=User)
# 书籍表
class Book(models.Model):
# 书名
title = models.CharField(max_length=32)
# 价格
price = models.CharField(max_length=32)
# 作者
author = models.CharField(max_length=32)
# 出版社
publish = models.CharField(max_length=32)
python manage.py makemigrations
python manage.py migrate
为用户表添加数据
使用ModelViewSet快速定义5个接口
* 4. 自动生成路由
from django.conf.urls import url
from django.contrib import admin
# 导入生成路由模块
from rest_framework import routers
# 导入视图层
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
# 生成简单路由对象
router_obj = routers.SimpleRouter()
# 生成books api接口
router_obj.register('api/books/v1', views.BookModelViewSet1)
# 将路由添加到路由列表中
urlpatterns += router_obj.urls
* 5. 定义模型序列化器
# 导入模型序列化器
from rest_framework import serializers
# 导入模型层
from app01 import models
# 定义模型序列化器
class BookModelSerializers(serializers.ModelSerializer):
# 定义Meta类
class Meta:
# 使用的表
model = models.Book
# 序列化的字段
fields = '__all__'
* 6. 定义视图类
from django.shortcuts import render
# Create your views here.
# 导入视图集
from rest_framework.viewsets import ModelViewSet
# 导入模型层
from app01 import models
# 导入模型序列化器
from app01.serializer import BookModelSerializers
# 书籍API
class BookModelViewSet1(ModelViewSet):
# 获取表中所有的模型对象
queryset = models.Book.objects.all()
# 使用的序列化器
serializer_class = BookModelSerializers
* 7. 登入功能路由
# 登入校验路由
url(r'^login/', views.Login.as_view())
* 8. 登入校验视图类
# 导入APIView
from rest_framework.views import APIView
# 导入响应对象
from rest_framework.response import Response
# 导入随机字符串
import uuid
# 登入功能
class Login(APIView):
# 定义登入方法
def post(self, request):
# 获取request中用户提交的数据去用户表中校验
username = request.data.get('username')
password = request.data.get('password')
# 判断用户名称或用户密码是否为空
if not (username and password):
return Response({
'code': 101, 'msg': '用户名称或密码不能为空!'})
# 去数据库中校验
user_obj = models.User.objects.filter(username=username, password=password).first()
# 判断检验结果
if not user_obj:
return Response({
'code': 102, 'msg': '用户名称或密码不正确!'})
# 生成token值
value = uuid.uuid4()
# 将token值存入数据表中, 没有则创建有则更新
models.Token.objects.update_or_create(defaults={
'value': value}, user=user_obj)
# 返回token值
return Response({
'code': 200, 'msg': '验证成功!', 'token': value})
* 9. 测试
* 10 认证类
# 导入认证类
from rest_framework.authentication1 import BaseAuthentication
# 导入模型层
from app01 import models
# 导入异常模块
from rest_framework.exceptions import AuthenticationFailed
# 定义认证类
class LoginAuthentication(BaseAuthentication):
# 校验方法
def authenticate(self, request):
# 获取request中携带的token值
token = request.data.get('token')
print(token)
# 没有token值, 抛异常
if not token:
raise AuthenticationFailed('没有携带token值!')
# 去数据库中校验
token_obj = models.Token.objects.filter(value=token).first()
# 判断校验是否成功
if not token_obj:
raise AuthenticationFailed('校验失败!')
# 校验成功, 返回两个数据
return token_obj.user, token
* 11. 登入认证
# 全局登入校验
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['books_msg.authenticates.LoginAuthentication', ]
}
# 为登入功能设置局部不校验, 不设置就没法登入了.
# 登入功能
class Login(APIView):
# 登入不校验token
authentication_classes = []
...
* 12 校验
1. 权限认证
权限(Permissions): 可以限制用户对于视图的访问和对具体数据的操作.
权限认证一定是在经过登入认证, 才能进行权限认证, 权限认证默认所有的用户访问都允许.
登入认证将将用户数据对象返回, 被request.user接收, 权限认证再将用户的数据对象取出来做权限的判断.
在dispatch方法中执行请求方法前, 会先进行视图访问权限判断
在通过get_object()获取具体对象时, 会进行模型对象访问权限的判断.
1.1 源码
APIView的dispatch方法中,视图类对象触发initial()方法.
self.check_permissions(request)
def check_permissions(self, request):
"""
Check if the request should be permitted.
Raises an appropriate exception if the request is not permitted.
"""
# 遍历类别拿出一个个的权限对象
for permission in self.get_permissions(): # 权限类对象, 可以有多个, 存放在列表中
# 执行权限对象的has_permission方法, 返回值为True则认证通过,什么都不做
if not permission.has_permission(request, self):
# 权限认证不通过执行permission_denied方法,
self.permission_denied(
request, message=getattr(permission, 'message', None)
)
permission.has_permission(request, self),
has_permission接收了三个参数, 第一个permission, 权限类对象self, request对象, self视图类对象.
在自定义的视图类中定义permission_class的属性值, 存放权限类的类名.
如果自己没有定义就会去配置文件中查找...
1.2 权限类
* 1 新建一个类, 该类继承BasePermission, 类中必须实现has_permission方法, 该方法中写逻辑,
给权限返回True, 不给权限返回False
局部设置 在类中定义permission_classes
permission_classes = [权限类]
局部禁用
permission_classes = []
全局设置 在settings.py 设置
REST_FRAMEWORK={
'DEFAULT_PERMISSION_CLASSES': ['权限类地址',], }
# 导入权限基类
from rest_framework.permissions import BasePermission
# 定义权限类
class RootPermission(BasePermission):
# 定义权限方法
def has_permission(self, request, view):
# 将 request.user 中数据对象的身份字段 取出来
# 取数字
identity_int = request.user.identity
# get_字段_display() 取数字对应的描述值
identity_str = request.user.get_identity_display()
print(identity_int, identity_str)
# 限制只有小米1才能通过,
if identity_int != 3:
print('权限认证成功!')
return True
else:
print('没有权限!')
return False
* 2. 建一个测试数图类
# 局部权限测试路由
url(r'^test/', views.Test.as_view())
# 导入权限类
from app01.permissions1 import RootPermission
# 测试视图类
class Test(APIView):
# 局部认证
permission_classes = [RootPermission]
per = [RootPermission, ]
def post(self, request):
return Response('权限通过!')
* 3. 测试
携带token去访问Test
小米1 对应的token 42243e2c-564e-4110-a503-92f482cebf46
小米3 对应的token 847ed6a9-c8e5-4fab-9e7c-ed93d73c9a6d
* 4. 设置为全局权限认证
# settings.py 中设置全局配置认证类
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentication1.LoginAuthentication', ],
'DEFAULT_PERMISSION_CLASSES': ['app01.permissions1.RootPermission'],
}
# 登入功能
class Login(APIView):
# 登入不校验token, 不认证权限
authentication_classes = []
permission_classes = []
1.3 内置权限
* 1. 为内置用户表创建超级管理员账户
python3.6 manage.py createsuperuser
用户名: Python
密码: zxc123456
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jEP4OrbW-1650612625754)(C:/Users/13600/AppData/Roaming/Typora/typora-user-images/image-20220421132629797.png)]
* 2. 测试路由
# 内置权限测试
url(r'^test2/', views.Test2.as_view())
* 3. 测试视图类
# 内置登入认证类
from rest_framework.authentication1 import SessionAuthentication
# 内置权限认证类
from rest_framework.permissions import IsAdminUser
# 内置权限测试
class Test2(APIView):
authentication_classes = [SessionAuthentication, ]
permission_classes = [IsAdminUser]
# 请求方法
def post(self, request):
return Response('权限通过!')
* 4. 超级用户登录到admin后台管理, 在再访问test2
权限判断是用户表的is_staff字段的值
将值修改为false在测试
1 - true
0 - false
2. 频率
频率: 用户一定时间内访问的次数.
限流: Throttling, 可以对接口的频次进行限制, 以此减轻服务器的压力.
2.1 内置的频率限制
# 导入
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle, ScopedrATEtHROTTLE
1. AnonRateThrottle 限制所有的未认证用户, 使用的ip区分用户.
使用DEFAULT_THROTTLE_RATES['anon': '次数/m'] 设置频次
2. UserRateThrottle 限制认证用户, 使用User id来区分.
使用DEFAULT_THROTTLE_RATES['user': '次数/m'] 设置频次
3. ScopedrATEtHROTTLE 限制用户对每个视图的访问频次, 使用ip或user id区分
次数/m 每分钟多少次, /后面只要是m开头即可, mzz, mxx, 都可以, 源码中截取开头第一个字符...
second秒 minute分钟 hour小时 day天
2.2 未登入限制
1. 全局配置
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle',] 'DEFAULT_THROTTLE_RATES': {
'anon': '3/m', },
DEFAULT_THROTTLE_CLASSES属性对应使用的限制模块,
每配置一个频率限制就需要有一个对应DEFAULT_THROTTLE_RATES, 在该属性中配置限制模式.
* 限制未登入用户的每分钟可以访问3次. 将认证和权限关闭.
# 全局配置认证类
REST_FRAMEWORK = {
# 使用AnonRateThrottle模块
'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle', ],
# 现在所有频率模块的频次 anon模块的频次 每分钟3次
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m', },
}
* 1. 测试路由
# 未登入频次限制
url(r'^test3/', views.Test3.as_view()),
* 2. 测试视图
# 频次测试
class Test3(APIView):
def get(self, request):
return Response('test3!')
* 3. 测试
get请求 127.0.0.1:8000/test3/
2. 局部配置
为需要的视图类设置 throttle_classes属性,
throttle_classes = [限制类]
# 全局配置认证类中配置频次
REST_FRAMEWORK = {
# 现在所有频率模块的频次 anon模块的频次 每分钟3次
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m', },
}
# 频次测试
from rest_framework.throttling import AnonRateThrottle
class Test3(APIView):
# 局部设置当前类使用的限流模块
throttle_classes = [AnonRateThrottle, ]
def get(self, request):
return Response('test3!')
局部配置测试
2.3 登入用户限制
限制登入的用户每分钟可以访问5次. 将登入验证打开.
过程简诉: 登入认证之后, 将用户的数据封装到requesr.user中, 使用UserRateThrottle,
需要用户数据有有一个is_authenticated字段, 作为认证的依据.
为用户表添加is_authenticated字段
# 用户表
class User(models.Model):
# 用户名称
username = models.CharField(max_length=32)
# 用户密码
password = models.CharField(max_length=32)
# 身份标识
identity = models.IntegerField(choices=((1, '小米1'), (2, '小米2'), (3, '小米3')))
# 认证标识, 默认为True
is_authenticated = models.BooleanField(default=True)
python manage.py makemigrations
python manage.py migrate
1. 全局配置
可以同时配置AnonRateThrottle 与 UserRateThrottle.
# 全局配置认证类
REST_FRAMEWORK = {
# 开启token认证
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentication1.LoginAuthentication', ],
# 配置频次
'DEFAULT_THROTTLE_CLASSES': [
# AnonRateThrottle模块限制未登入的访问频次
'rest_framework.throttling.AnonRateThrottle',
# UserRateThrottle模块现在登入的访问频次
'rest_framework.throttling.UserRateThrottle',
],
# 现在所有频率模块的频次 (未登入频次 每分钟3次) (登入频次 每分钟5次)
'DEFAULT_THROTTLE_RATES': {
'anon': '3/m', 'user': '5/m'},
}
* 1. 测试路由
# 登入用户频次限制
url(r'^test4/', views.Test4.as_view()),
* 2. 测试视图类
# 登入用户频次测试
class Test4(APIView):
# 开启频次限制
def post(self, request):
return Response('test4!')
* 3. 测试, 携带token
post: 127.0.0.1:8000/test4/
提交数据:
{
"token": "42243e2c-564e-4110-a503-92f482cebf46"
}
2.局部配置
将全局的配置注释掉, 在测试视图中设置 throttle_classess属性.
# 全局配置认证类
REST_FRAMEWORK = {
# 认证token
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentication1.LoginAuthentication', ],
# 现在所有频率模块的频次 未登入频次 每分钟3次 登入频次每分钟5次
'DEFAULT_THROTTLE_RATES': {
'anon' 'user': '5/m'},
}
from rest_framework.throttling import UserRateThrottle
class Test4(APIView):
throttle_classes = [UserRateThrottle, ]
# 开启频次限制
def post(self, request):
return Response('test4!')
3. 使用内置权限
使用SessionAuthentication, 作为登入认证检, 请求换为get.
# 登入用户频次测试
# auth模块登入认证
from rest_framework.authentication import SessionAuthentication
# 登入访问限制模块
from rest_framework.throttling import UserRateThrottle
class Test4(APIView):
# 使用auth模块的认证
authentication_classes = [SessionAuthentication]
# 登入账户频率限制
throttle_classes = [UserRateThrottle, ]
# 开启频次限制
def get(self, request):
return Response('test4!')
3. 过滤
过滤Filtering, 在继承值GenericAPIview的视图类, 在获取所有数据时, 可以设置根据字段进行过滤数据.
需要视图类有queryset属性的值, 拿出做处理. APIview不满足这个条件.
需要安装dango-filter模块
pip install django-filter
3.1 准备环境
* 1. 为book表添加数据
基于ListAPIView写一个查询所有数据的接口
* 2. 过滤测试路由
# 过滤测试
url(r'^books/', views.BookListAPIView.as_view())
* 3. 过滤测试视图类
from rest_framework.generics import ListAPIView
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
* 4. 查询测试
3.2 全局配置
* 1. settings.py配置文件的app应用列表中注册 django_filter
INSTALLED_APPS = [
...
'rest_framework',
]
* 2. 全局配置
REST_FRAMEWORK = {
...
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
* 3. 在视图类中添加filter_fields属性, 指定可以过滤的字段
from rest_framework.generics import ListAPIView
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
# 指定需要过滤的字段
filter_fields = ['title', 'publish']
* 4. 过滤查询测试, 单条件测试
* 5. 过滤查询测试, 多个条件测试, 关系为and.
3.3 局部配置
# 导入过滤类
from django_filters.rest_framework import DjangoFilterBackend
# 视图类中设置filter_backends属性值
filter_backends = [DjangoFilterBackend]
* 1. 局部配置
from rest_framework.generics import ListAPIView
from django_filters.rest_framework import DjangoFilterBackend
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
filter_backends = [DjangoFilterBackend]
# 指定需要过滤的字段
filter_fields = ['title', 'publish']
* 2. 过滤测试
4. 排序
在视图类中设置filter_backends, rest_framework.OrderingFilter过滤器, rest_framework会在请求的查询
字符串参数中包含了ordering参数, 如果包含ordering参数, 则按照ordering参数指明的字段对数据集合进行排序.
在视图类中设置ordering_fields属性设置可选字段, 在前端传递ordering参数.
4.2 局部配置
# 导入排序模块
from rest_framework.filters import OrderingFilter
# 视图类的 filter_backends属性 设置排序模块
filter_backends = [OrderingFilter]
# 视图类的 ordering_fields 属性设置可以排序的字段
ordering_fields = ('id',)
?ordering=id 默认排序
?ordering=-id 倒序
4.1 全局配置
# 全局配置认证类
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['rest_framework.filters.OrderingFilter',],
}
from rest_framework.generics import ListAPIView
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
# 定义可以排序的字段
ordering_fields = ('id',)
GET请求: 127.0.0.1:8000/books/?ordering=-id
4.2 局部配置
from rest_framework.generics import ListAPIView
from rest_framework.filters import OrderingFilter
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
filter_backends = [OrderingFilter]
ordering_fields = ('id',)
GET请求: 127.0.0.1:8000/books/?ordering=-id
4.3 过滤排序
1. 全局配置
# 全局配置认证类
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
# 过滤排序
'django_filters.rest_framework.DjangoFilterBackend',
# 过滤排序
'rest_framework.filters.OrderingFilter', ],
}
from rest_framework.generics import ListAPIView
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
# 过滤的字段
filter_fields = ['publish']
# 排序的字段
ordering_fields = ('id',)
GET请求: 127.0.0.1:8000/books/?publish=aa出版社&ordering=-id
4.2 局部使用
* 注意点, filter_backends设置会覆盖全局设置! 如果需要配合使用就在局部设置中定义过滤排序模块.
from rest_framework.generics import ListAPIView
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
class BookListAPIView(ListAPIView):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
# 过滤排序
filter_backends = [DjangoFilterBackend, OrderingFilter]
# 过滤的字段
filter_fields = ['publish']
# 排序的字段
ordering_fields = ('id',)
GET请求: 127.0.0.1:8000/books/?publish=aa出版社&ordering=-id
5. 异常处理
5.1 源码解析
APIView的内置异常模块
异常处理主要是组成返回给前端的响应信息
返回信息的封装追溯
只针对三大认证做了返回信息的处理, 其他的直接返回None.
5.2 自定义异常响应
只能全局配置, 自定义的异常响应, 值就是一个字符串, 不能是列表['自定义的异常响应']
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': '自定义的异常响应',
}
* 1. 自定义异常响应模块
# 导入异常处理程序
from rest_framework.views import exception_handler
# 导入状态码模块
from rest_framework import status
# 自定义异常响应
def exception_response(exc, context):
response = exception_handler(exc, context)
"""
response 的值有两种情况
1. 三大认证异常的返回响应格式
2. 其他的异常没有处理 返回None
"""
# 判断response 的值是否为None
if not response:
# 按异不同的异常 自定义异常响应信息
if isinstance(exc, ...):
return Response(data={
'code': 401, 'msg': str(exc)}, status=status.HTTP_401_UNAUTHORIZED)
if isinstance(exc, Exception):
return Response(data={
'code': 402, 'msg': str(exc)}, status=status.HTTP_402_PAYMENT_REQUIRED)
# 重新封装三大认证的返回值, 从response.data 中取出错误的信息 detail
return Response(data={
'code': 400, 'msg': response.data.get('detail')}, status=status.HTTP_400_BAD_REQUEST)
* 2. 全局配置
# 全局配置认证类
REST_FRAMEWORK = {
# 认证
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentication1.LoginAuthentication', ],
# 权限
'DEFAULT_PERMISSION_CLASSES': ['app01.permissions1.RootPermission'],
# 自定义异常响应
'EXCEPTION_HANDLER': 'app01.response.exception_response',}
* 3. 测试路由
# 自动生成 异常响应测试路由
url(r'^books2/', views.BookListAPIView2.as_view()),
* 4. 测试视图类
from django.conf.urls import url
from django.contrib import admin
# 导入生成路由模块
from rest_framework import routers
# 导入视图层
from app01 import views
urlpatterns = [
...
]
# 生成简单路由对象
router_obj = routers.SimpleRouter()
# 生成books api接口
router_obj.register('api/books/v1', views.BookListAPIView2)
# 将路由添加到路由列表中
urlpatterns += router_obj.urls
* 5. 测试视图类
from rest_framework.decorators import action
class BookListAPIView2(ModelViewSet):
# 设置queryset 属性
queryset = models.Book.objects.all()
# 使用的模型序列化器
serializer_class = BookModelSerializers
@action(methods=['get',], detail=False)
def get_two_obj(self, request):
1/0
return Response({
'两条数据'})
* 6. 自定义异常响应
# 自定义异常响应
from rest_framework.views import exception_handler
from rest_framework import status
from rest_framework.response import Response
def exception_response(exc, context):
print(exc, context)
response = exception_handler(exc, context)
"""
response 的值有两种情况
1. 三大认证异常的返回响应格式
2. 其他的异常没有处理 返回None
"""
# 判断response 的值是否为None
if not response:
# 按异不同的异常 自定义异常响应信息
if isinstance(exc, ZeroDivisionError):
return Response(data={
'code': 401, 'msg': str(exc)}, status=status.HTTP_401_UNAUTHORIZED)
if isinstance(exc, Exception):
return Response(data={
'code': 402, 'msg': str(exc)}, status=status.HTTP_402_PAYMENT_REQUIRED)
# 重新封装三大认证的返回值, 从response.data 中取出错误的信息 detail
return Response(data={
'code': 400, 'msg': response.data.get('detail')}, status=status.HTTP_400_BAD_REQUEST)
* 7. 登入认证测试
get请求不带token访问: 127.0.0.1:8000/api/books/v1/
* 8. 权限测试, 带权限不能通过的...
get请求带token访问: 127.0.0.1:8000/api/books/v1/
小米1 对应的token 42243e2c-564e-4110-a503-92f482cebf46
小米3 对应的token 847ed6a9-c8e5-4fab-9e7c-ed93d73c9a6d
* 9. 自定义认证器中编写代码出现异常, 手动添加异常.
get请求带token访问: 127.0.0.1:8000/api/books/v1/get_two_obj/
get请求带满足权限的token访问: 127.0.0.1:8000/api/books/v1/get_two_obj/
* 10. 请求中编写代码出现异常
get请求带满足权限的token访问: 127.0.0.1:8000/api/books/v1/get_two_obj/
6. 封装Response
继承Response类, 重新定义返回数据的格式.
* 1. 响应类
from rest_framework import status
from rest_framework.response import Response
from rest_framework.status import *
# 正常响应
class NormalResponse(Response):
def __init__(self, code=200, msg='访问成功', data=None, status=HTTP_200_OK, **kwargs):
"""
:param code: 状态码
:param msg: 返回信息
:param data: 获取的数据
:param status: 状态码
:param kwargs: 其他参数
"""
# 生成包含code 与 msg 的字段
dic = {
'code': code, 'msg': msg}
# 判断data是否有值
if data:
# 将获取的数据data添加到字典
dic.update(data=data)
# 将其他参数添加到字典
dic.update(kwargs)
# 调用父类的方法生成对象
super().__init__(data=dic, status=status)
* 2. 测试路由
# 响应测试
url(r'^test5/', views.TestAPIView.as_view())
* 3. 测试路由
from rest_framework.views import APIView
# 自定义响应对象
from app01.response import NormalResponse
class TestAPIView(APIView):
def get(self, request):
return NormalResponse(data={
'id': 1, 'title': '小说1'})
get请求: 127.0.0.1:8000/test5/
return NormalResponse(data={
'id': 1, 'title': '小说1'}, token='xadasdadasd')
return NormalResponse(101, '失败', status=status.HTTP_101_SWITCHING_PROTOCOLS)