前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >3. DRF进阶之DRF视图和常用功能

3. DRF进阶之DRF视图和常用功能

作者头像
alexhuiwang
发布2023-01-16 09:11:26
4.2K0
发布2023-01-16 09:11:26
举报
文章被收录于专栏:运维博客运维博客

DRF视图和常用功能

DRF视图

DRF视图类介绍

在DRF框架中提供了众多的通用视图基类与扩展类,以简化视图的编写。

  • View:Django默认的视图基类,负责将视图连接到URL,HTTP请求方法的基本调度,之前写类视图一般都用这个。
  • APIView:DRF提供的所有视图的基类,继承View并扩展,具备了身份认证、权限检查、流量控制等功能。
  • GenericAPIView:对APIView更高层次的封装,例如增加分页、过滤器
  • GenericViewSet:继承GenericAPIView和ViewSet
  • ViewSet:继承APIView,并结合router自动映射路由
  • ModelViewSet:继承GenericAPIView和五个扩展类,封装好各种请求,更加完善,业务逻辑基本不用自己写了。
image-20230110213341815
image-20230110213341815

APIView类

APIView:DRF提供的所有视图的基类,继承View并扩展,具备了身份认证、权限检查、流量控制等功能

  1. 创建项目
image-20230110215511390
image-20230110215511390
  1. 创建app并加入settings.py
代码语言:javascript
复制
E:\workspace\django-project\day2\django_drf>python manage.py startapp myapp
  1. 项目主路由配置: django_drf/urls.py
image-20230110220005720
image-20230110220005720
  1. 创建项目视图: myapp/views.py
代码语言:javascript
复制
from rest_framework.views import APIView
from rest_framework.response import Response

class UserAPIView(APIView):
    def get(self,request):
        data = {'result': 'get'}
        return Response(data)
    def post(self,request):
        data = {'result': 'post'}
        return Response(data)
    def put(self,request):
        data = {'result': 'put'}
        return Response(data)
    def delete(self,request):
        data = {'result': 'delete'}
        return Response(data)
  1. 项目路由配置: myapp/urls.py
代码语言:javascript
复制
from django.urls import re_path
from myapp import views

urlpatterns = [
    re_path('^users1/$', views.UserAPIView.as_view())
]
  1. 项目启动测试
image-20230110220858986
image-20230110220858986
  1. 浏览器访问测试: http://127.0.0.1:8000/myapp/users1/
image-20230110220940483
image-20230110220940483

Request与Response

Request

DRF传入视图的request对象不再是Django默认的HttpRequest对象,而是基于HttpRequest类扩展后的Request类的对象。

Request对象的数据是自动根据前端发送的数据统一解析数据格式。

  • 常用属性:
    • request.data:返回POST提交的数据,与request.POST类似
    • request.query_params:返回GET URL参数,与request.GET类似
image-20230110222203488
image-20230110222203488
  1. 浏览器get测试: http://127.0.0.1:8000/myapp/users1/?a=123&b=456
  2. 查看get_params数据
image-20230110222312341
image-20230110222312341
  1. post数据测试
image-20230110222445207
image-20230110222445207
  1. 查看request.data数据
image-20230110222553893
image-20230110222553893
get和post提交数据场景和特点
  • get
    • 获取数据
    • 提交数据有长度限制
    • 传输是明文形式
  • post
    • 提交数据
    • 提交数据无长度限制
    • 请求body中提交数据,安全系数较高
Response

DRF提供了一个响应类Reponse,响应的数据会自动转换符合前端的JSON数据格式。

导入:

from rest_framework.response import Response

格式:

Response(data, status=None, template_name=None, headers=None, content_type=None)

  • data:响应序列化处理后的数据,传递python对象
  • status:状态码,默认200
  • template_name:模板名称
  • headers:用于响应头信息的字典
  • content_type:响应数据的类型

使用方法:

return Reponse(data=data, status=status.HTTP_404_NOT_FOUND)

image-20230110223812211
image-20230110223812211

为了方便设置状态码,rest_framework.status模块提供了所有HTTP状态码,以下是一些常用的:

代码语言:javascript
复制
HTTP_200_OK:请求成功
HTTP_301_MOVED_PERMANENTLY:永久重定向
HTTP_302_FOUND:临时重定向
HTTP_304_NOT_MODIFIED:请求的资源未修改
HTTP_403_FORBIDDEN:没有权限访问
HTTP_404_NOT_FOUND:页面没有发现
HTTP_500_INTERNAL_SERVER_ERROR:服务器内部错误
HTTP_502_BAD_GATEWAY:网关错误
HTTP_503_SERVICE_UNAVAILABLE:服务器不可达
HTTP_504_GATEWAY_TIMEOUT:网关超时

GenericAPIView

  • GenericAPIView对APIView更高层次的封装,实现以下功能:
    • 增加queryset属性,指定操作的数据,不用再将数据传给序列化器,会自动实现。
    • 增加serializer_class属性,直接指定使用的序列化器
    • 增加过滤器属性:filter_backends
    • 增加分页属性:pagination_class
    • 增加lookup_field属性和实现get_object()方法:用于获取单条数据,可自定义默认分组名(pk)
  1. 基于上面的项目新增app模型: myapp/models.py
代码语言:javascript
复制
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=64)
    sex = models.CharField(max_length=8)
    age = models.IntegerField()
  1. 新增app序列化: myapp/serializers.py
代码语言:javascript
复制
from myapp.models import User
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'
  1. 新增测试数据
代码语言:javascript
复制
E:\workspace\django-project\day2\django_drf>python manage.py makemigrations
E:\workspace\django-project\day2\django_drf>python manage.py migrate
E:\workspace\django-project\day2\django_drf>python manage.py shell
In [1]: from myapp.models import User
In [2]: User.objects.create(name="张三",city="北京市",sex="男",age=29)
In [3]: User.objects.create(name="李四",city="上海市",sex="女",age=19)
In [4]: User.objects.create(name="阿山",city="广州市",sex="女",age=23)
In [5]: User.objects.create(name="阿妖",city="深圳市",sex="男",age=21)
  1. 创建app视图类: myapp/views.py
代码语言:javascript
复制
from myapp.models import User
from rest_framework.generics import GenericAPIView
from .serializers import UserSerializer
from rest_framework.response import Response

class UserGenericAPIViews(GenericAPIView):
    queryset = User.objects.all()  #指定操作的数据
    serializer_class = UserSerializer   #指定序列化器
    lookup_field = 'id'
    def get(self,request, id=None):
        if id:
            user_obj = self.get_object()   #从类方法调用指定数据,不需要传id
            user_ser = self.get_serializer(user_obj)
        else:
            quertset = self.get_queryset()  #从类方法调用所有数据
            user_ser = self.get_serializer(quertset, many=True) #从类方法调用序列化器
        result = {"code": 200, "msg": "success", "data": user_ser.data}
        return Response(result)

    def post(self,request):
        user_ser = self.get_serializer(data=request.data)
        user_ser.is_valid(raise_exception=True)
        user_ser.save()
        result = {"code": 200, "msg": "create success"}
        return Response(result)

    def put(self,request,id=None):
        user_obj = self.get_object()
        user_ser = self.get_serializer(instance=user_obj,data=request.data)
        user_ser.is_valid(raise_exception=True)
        result = {"code": 200, "msg": "update success"}
        return Response(result)
    
    def delete(self,request,id=None):
        user_obj = self.get_object()
        user_obj.delete()
        result = {"code": 200, "msg": "delete success"}
        return Response(result)
  1. 创建app路由: myapp/urls.py
代码语言:javascript
复制
from django.urls import re_path
from myapp import views

urlpatterns = [
    re_path('^users1/$', views.UserAPIView.as_view()),
    re_path('^users2/$',views.UserGenericAPIViews.as_view()),  #获取所有数据和创建
    re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()),  #获取单条数据及其更新,删除
]
  1. 功能测试
代码语言:javascript
复制
http://127.0.0.1:8000/myapp/users2/    #list,post
http://127.0.0.1:8000/myapp/users2/5/  #指定id数据的更新,删除,查看
image-20230110232746539
image-20230110232746539
image-20230110232731618
image-20230110232731618

ViewSet类

GenericAPIView已经完成了许多功能,但会有一个问题,获取所有用户列表和单个用户需要分别定义两个视图和URL路由,使用ViewSet可以很好解决这个问题,并且实现了路由自动映射

ViewSet视图集不再实现get()、post()等方法,而是实现以下请求方法动作:

代码语言:javascript
复制
 list():获取所有数据
 retrieve():获取单个数据
 create():创建数据
 update():更新数据
 destory():删除数据
  1. 修改app视图类: myapp/views.py
代码语言:javascript
复制
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from myapp.models import User
from .serializers import UserSerializer

class UserViewSet(ViewSet):
	lookup_field = 'id'    #自动注册路由的时候需要用这个
    def list(self,request):
        user_obj = User.objects.all()
        user_ser = UserSerializer(user_obj, many=True)
        result = {"code": 200, "msg": "success", "data": user_ser.data}
        return Response(result)

    def retrieve(self,request,id=None):
        user_obj = User.objects.get(id=id)
        user_ser = UserSerializer(user_obj)
        result = {"code": 200, "msg": "success", "data": user_ser.data}
        return Response(result)

    def update(self,request,id=None):
        user_obj = User.objects.get(id=id)
        user_ser = UserSerializer(instance=user_obj,data=request.data)
        user_ser.is_valid(raise_exception=True)
        user_ser.save()
        result = {"code": 200, "msg": "update success"}
        return Response(result)

    def create(self,request):
        user_ser = UserSerializer(data=request.data)
        user_ser.is_valid(raise_exception=True)
        user_ser.save()
        result = {"code": 200, "msg": "create success"}
        return Response(result)

    def destory(self,request,id=None):
        user_obj = User.objects.get(id=id)
        user_obj.delete()
        result = {"code": 200, "msg": "delete success"}
        return Response(result)
  1. 修改app的路由: myapp/urls.py
代码语言:javascript
复制
from django.urls import re_path
from myapp import views

urlpatterns = [
    re_path('^users1/$', views.UserAPIView.as_view()),
    re_path('^users2/$',views.UserGenericAPIViews.as_view()),  #获取所有数据和创建
    re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()),  #获取单条数据及其更新,删除
    re_path('^users3/$',views.UserViewSet.as_view({'get': 'list','post': 'create'})),  #获取所有数据和创建
    re_path('^users3/(?P<id>\d+)/$',views.UserViewSet.as_view({'get': 'retrieve','put': 'update','delete': 'destory'})),  #获取单条数据及其更新,删除
]
  1. 功能测试
代码语言:javascript
复制
http://127.0.0.1:8000/myapp/users3/    #list,post
http://127.0.0.1:8000/myapp/users3/5/  #指定id数据的更新,删除,查看
路由自动注册
  1. 修改app路由: myapp/urls.py
代码语言:javascript
复制
from django.urls import re_path,include
from myapp import views
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register('user4',views.UserViewSet,'user4')
router.register('user5',views.UserViewSet,'user5')  #再次注册

urlpatterns = [
    re_path('^users1/$', views.UserAPIView.as_view()),
    re_path('^users2/$',views.UserGenericAPIViews.as_view()),  #获取所有数据和创建
    re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()),  #获取单条数据及其更新,删除
    re_path('^users3/$',views.UserViewSet.as_view({'get': 'list','post': 'create'})),  #获取所有数据和创建
    re_path('^users3/(?P<id>\d+)/$',views.UserViewSet.as_view({'get': 'retrieve','put': 'update','delete': 'destory'})),  #获取单条数据及其更新,删除
    re_path('^api/',include(router.urls))
]
  1. 测试功能
代码语言:javascript
复制
http://127.0.0.1:8000/myapp/api/     #查看注册的url列表
http://127.0.0.1:8000/myapp/api/user4/   #list,post
http://127.0.0.1:8000/myapp/api/user4/2/   #指定id数据的更新,删除,查看
image-20230112231436534
image-20230112231436534

ModelViewSet类

由于ModelViewSet有较高的抽象,实现自动增删改查功能。对于增、改在很多场景无法满足需求,这就需要重写对应方法了。

  • 示例:重写create()方法,修改数据和响应内容格式
  1. 新增app视图: myapp/views.py
代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet
class UserModelViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
  1. app路由注入: myapp/urls.py
代码语言:javascript
复制
from django.urls import re_path,include
from myapp import views
from rest_framework.routers import DefaultRouter

router = DefaultRouter()
router.register('user4',views.UserViewSet,'user4')
router.register('user5',views.UserViewSet,'user5')
router.register('user6',views.UserModelViewSet,'user6')    #注入ModelViewSet

urlpatterns = [
    re_path('^users1/$', views.UserAPIView.as_view()),
    re_path('^users2/$',views.UserGenericAPIViews.as_view()),  #获取所有数据和创建
    re_path('^users2/(?P<id>\d+)/$',views.UserGenericAPIViews.as_view()),  #获取单条数据及其更新,删除
    re_path('^users3/$',views.UserViewSet.as_view({'get': 'list','post': 'create'})),  #获取所有数据和创建
    re_path('^users3/(?P<id>\d+)/$',views.UserViewSet.as_view({'get': 'retrieve','put': 'update','delete': 'destory'})),  #获取单条数据及其更新,删除
    re_path('^api/',include(router.urls))
]
  1. 接口测试
代码语言:javascript
复制
http://127.0.0.1:8000/myapp/api/     #查看注册的url列表
http://127.0.0.1:8000/myapp/api/user6/  #list,create
http://127.0.0.1:8000/myapp/api/user6/  #update, delete, retrieve
image-20230112233857370
image-20230112233857370

DRF常用功能

主流认证方式

Session认证

HTTP是一个无状态的协议,每次访问都是新的,早期主要用于浏览网页,随着时代发展,像在线购物网站的兴起,就面临着记录哪些人登录系统,哪些人购物车里放了商品。也就是必须每个人区分开,所以就有了用户名来标识,但每次访问页面都要登录,非常麻烦,这就有了会话保持。Cookie+Session就是实现会话保持的技术。

image-20230113000025881
image-20230113000025881
Token

Cookie+Session通常在浏览器作为客户端的情况下比较通用,随着前后端分离开发模式的普及,会涉及到多端(PC、APP、Pad),特别是手机端,支持Cookie不友好,并且Cookie不支持跨域,因此基于这些局限性,Token逐渐主流。

image-20230113002800228
image-20230113002800228
JWT

与普通Token一样,都是访问资源的令牌,区别是普通Token服务端验证token信息要查询数据库验证,JWT验证token信息不用查询数据库,只需要在服务端使用密钥效验。与普通Token一样,都是访问资源的令牌,区别是普通Token服务端验证token信息要查询数据库验证,JWT验证token信息不用查询数据库,只需要在服务端使用密钥效验。

image-20230113002822705
image-20230113002822705

DRF认证

目前DRF可任意访问,没有任何限制,是不符合生产环境标准的,因此接下来学习认证实现访问控制。

  • DRF支持四种认证方式:
    • BasicAuthentication:基于用户名和密码的认证,适用于测试
    • SessionAuthentication:基于Session的认证
    • TokenAuthentication:基于Token的认证
    • RemoteUserAuthentication:基于远程用户的认证
  • DRF支持权限:
    • IsAuthenticated:只有登录用户才能访问所有API
    • AllowAny:允许所有用户
    • IsAdminUser:仅管理员用户
    • IsAuthenticatedOrReadOnly:登录的用户可以读写API,未登录用户只读
DRF Session 认证
  • 参考文档: https://www.django-rest-framework.org/api-guide/authentication/#sessionauthentication

由于Django默认提供Session存储机制,可直接通过登录内置管理后台进行验证。当登录管理后台后,就有权限访问了。

  1. 新建内置登录后台密码
image-20230114224955896
image-20230114224955896
全局session认证
  1. settings.py全局配置(追加配置即可): django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}
  1. 重启项目
  2. 测试访问:http://127.0.0.1:8000/myapp/api/
image-20230114225744630
image-20230114225744630
  1. 登录后台: http://127.0.0.1:8000/admin/login/?next=/admin/
image-20230114225834670
image-20230114225834670
  1. 刷新api视图: http://127.0.0.1:8000/myapp/api/
image-20230114225926929
image-20230114225926929
局部(视图)session认证
  1. 注释全局settings.py中关于全局session认证的配置
image-20230114230155809
image-20230114230155809
  1. 修改app视图函数: myapp/views.py
代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated

class UserModelViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    #认证&权限配置
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]
  1. 视图对应的url测试: http://127.0.0.1:8000/myapp/api/user6/
image-20230114233709514
image-20230114233709514
  1. 对比 http://127.0.0.1:8000/myapp/api/user5/
image-20230114233750944
image-20230114233750944
Token认证
  1. 全局settings.py新增app: django_drf/settings.py
image-20230114233957832
image-20230114233957832
  1. 全局配置Token认证: django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    #认证
    'DEFAULT_AUTHENTICATION_CLASSES': [
        #'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ],
    #权限
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}
  1. 同步token数据库表
代码语言:javascript
复制
E:\workspace\django-project\day2\django_drf>python manage.py makemigrations
E:\workspace\django-project\day2\django_drf>python manage.py migrate
image-20230114234313922
image-20230114234313922
  1. 全局urls.py配置认证接口URL: django_drf/urls.py
代码语言:javascript
复制
from django.contrib import admin
from django.urls import path,include,re_path
from rest_framework.authtoken import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/',include("myapp.urls")),
    re_path('^auth_token/$', views.obtain_auth_token)
]
  1. 使用apipost生成token: http://127.0.0.1:8000/auth_token/
image-20230114234814281
image-20230114234814281
  1. 单纯访问测试: http://127.0.0.1:8000/myapp/api/user5/
image-20230114235533065
image-20230114235533065
  1. 带token测试: curl -H "Authorization: token ab87f8ab97dd0ffdd073546dea57c794ada6995e" http://127.0.0.1:8000/myapp/api/user5/
image-20230115000352030
image-20230115000352030
token自定义返回信息
  • 需要重写返回信息函数
  1. 在app项目下的utils目录中新增重写信息: myapp/utils/token_auth.py
代码语言:javascript
复制
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.response import Response
from rest_framework.authtoken.models import Token

class CustomAuthToken(ObtainAuthToken):
    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        return Response({'token': token.key, 'username': user.username})
  1. 修改全局urls中的token部分配置: django_drf/urls.py
代码语言:javascript
复制
from django.contrib import admin
from django.urls import path,include,re_path
# from rest_framework.authtoken import views
from myapp.utils.auth_token import CustomAuthToken
urlpatterns = [
    path('admin/', admin.site.urls),
    path('myapp/',include("myapp.urls")),
    re_path('^auth_token/$', CustomAuthToken.as_view())
]
  1. apipost测试: http://127.0.0.1:8000/auth_token/
image-20230115001632556
image-20230115001632556

限流

可以对接口访问的频率进行限制,以减轻服务器压力。

应用场景:投票、购买数量等

  • 官方文档: https://www.django-rest-framework.org/api-guide/throttling/#throttling
  1. 全局settings配置: django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    #认证
    'DEFAULT_AUTHENTICATION_CLASSES': [
        #'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ],
    #权限
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ],
    #限流
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/minute',
        'user': '10/minute'
    }
}
  1. 重启项目
  2. apipost 请求1分钟内请求10次之后结果如下:
image-20230115002940420
image-20230115002940420

过滤

  • 对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持
  • 参考文档: https://www.django-rest-framework.org/api-guide/filtering/
  1. 安装: django-filter
代码语言:javascript
复制
pip3 install django-filter
  1. 全局配置新增配置: djang_drf/settings.py
image-20230115003701122
image-20230115003701122
  1. 全局配置中新增过滤配置: django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    #认证
    # 'DEFAULT_AUTHENTICATION_CLASSES': [
    #     'rest_framework.authentication.SessionAuthentication',
    #     'rest_framework.authentication.TokenAuthentication',
    # ],
    #权限
    # 'DEFAULT_PERMISSION_CLASSES': [
    #     'rest_framework.permissions.IsAuthenticated',
    # ],
    #限流
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/minute',
        'user': '10/minute'
    },
    #过滤配置
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend']
}
  1. app视图中新增过滤字段: myapp/views.py
代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet

class UserModelViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    #过滤
    filter_fields = ('sex',)
  1. 页面测试:http://127.0.0.1:8000/myapp/api/user6/?sex=%E7%94%B7
image-20230115004413852
image-20230115004413852

搜索和排序

DRF提供过滤器帮助我们快速对字段进行搜索和排序

  1. 继续修改app视图中新增过滤字段: myapp/views.py
代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet
from rest_framework import filters

class UserModelViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    #过滤
    filter_fields = ('sex',)
    #搜索&排序
    filter_backends = [filters.SearchFilter,filters.OrderingFilter]
    search_fields = ('name',)
    order_fields = ('age',)
  1. 测试: http://127.0.0.1:8000/myapp/api/user6/?search=%E5%BC%A0%E4%B8%89
image-20230115005153208
image-20230115005153208

分页

分页是数据表格必备的功能,可以在前端实现,也可以在后端实现,为了避免响应数据过大,造成前端压力,一般在后端实现。

  • 参考文档: https://www.django-rest-framework.org/api-guide/pagination/#pagination
全局分页配置
  1. 修改全局settings配置: django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    #限流
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/minute',
        'user': '10/minute'
    },
    #过滤配置
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    #全局分页
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 3   #三条数据一页
}
  1. 接口测试: http://127.0.0.1:8000/myapp/api/user6/
image-20230115005832644
image-20230115005832644
自定义分页配置
  1. 新增自定义分页配置:myapp/utils/my_pagination.py
代码语言:javascript
复制
from rest_framework.pagination import PageNumberPagination
from collections import OrderedDict
from rest_framework.response import Response

class CustomPagination(PageNumberPagination):
    page_size = 10 #每页显式多少条数据
    page_query_param = 'page_num' #查询第几页数据
    page_size_query_param = 'page_size' #每页显式多少条
    max_page_size = 50  #每一页最大显式50条
    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('total_num', self.page.paginator.count),
            ('next_page', self.get_next_link()),
            ('msg', 'success'),
            ('code',200),
            ('previous_page', self.get_previous_link()),
            ('data', data)
        ]))
  1. 修改全局settings配置: django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    #限流
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/minute',
        'user': '10/minute'
    },
    #过滤配置
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    # 自定义分页
    'DEFAULT_PAGINATION_CLASS': 'myapp.utils.my_pagination.CustomPagination'
}
  1. 分页测试: http://127.0.0.1:8000/myapp/api/user6/?page_size=2&page_num=2
image-20230115011427559
image-20230115011427559

自动生成接口文档

由于项目开发经验欠缺或着急上线,需求不断改动,项目设计阶段定义的接口已经面目全非,这给前端开发人员参考带来一定困难,如何改善这个问题呢?

  • Swagger来了,它是一个应用广泛的REST API文档自动生成工具,生成的文档可供前端人员查看。
  • 文档参考:https://django-rest-swagger.readthedocs.io/en/latest/
  1. 安装django-rest-swagger
代码语言:javascript
复制
pip3 install django-rest-swagger
  1. 修改全局settings配置: django_drf/settings.py
image-20230115012014075
image-20230115012014075
  1. 修改全局settings配置: django_drf/settings.py
代码语言:javascript
复制
REST_FRAMEWORK = {
    #限流
    'DEFAULT_THROTTLE_CLASSES': [
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ],
    'DEFAULT_THROTTLE_RATES': {
        'anon': '10/minute',
        'user': '10/minute'
    },
    #过滤配置
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    # 自定义分页
    'DEFAULT_PAGINATION_CLASS': 'myapp.utils.my_pagination.CustomPagination',
    #接口文档
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
  1. 配置全局路由: django_drf/urls.py
image-20230115012424778
image-20230115012424778
  1. 访问测试: http://127.0.0.1:8000/docs/
image-20230115012531832
image-20230115012531832
  1. 修复上述问题: D:\devTools\python3\lib\site-packages\rest_framework_swagger\templates\rest_framework_swagger\index.html

将index.html中的第二行staticfiles改成static即可解决

  1. 重启项目测试: http://127.0.0.1:8000/docs/
image-20230115012929642
image-20230115012929642
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-01-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DRF视图和常用功能
    • DRF视图
      • DRF视图类介绍
      • APIView类
      • Request与Response
      • GenericAPIView
      • ViewSet类
      • ModelViewSet类
    • DRF常用功能
      • 主流认证方式
      • DRF认证
      • 限流
      • 过滤
      • 搜索和排序
      • 分页
      • 自动生成接口文档
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档