drf—过滤、分页、异常

发布时间 2023-09-07 20:13:53作者: 别管鱼油我了

session回顾

写一个登录接口——保存用户登录状态

签发阶段:做了三件事情:

  1、生成一个随机字符串

  2、django—session表中插入数据

  3、把随机字符串以cookie形式返回给前端(存在浏览器的cookie中)

认证阶段:

  前端自动携带cookie到后端,sessionid:随机字符串

session的流程:

  前端写登录和密码后会将用户名和密码携带

  在视图函数中写一个登录接口,取出用户携带的用户名和密码,去数据库里查询,如果查得到就是已经登录,设置session,例如request.session[name],并且返回四件套。

  在中间件中自动完成的事情:1、生成一个随机字符串。2、把字符串和数据存到django-session 3、把随机字符串返回给浏览器

  浏览器将随机字符串存进了sessionid中。在需要登录才能访问接口,浏览器会自动把cookie携带访问的网址。

  中间件又做了三件事:1、取出随机字符串  2、通过随机字符串去django-session中查询 3、把data的数据以字典的形式放到request.session中

  下次就可以取出前面保存的数据

 自己写的登录接口本质原理也是session的认证机制,session是存储在服务端的键值对。

 

过滤

 只针对查询所有接口

必须继承GenericAPIView

需要安装模块

    pip install django==3.2.12
    pip install django-filter

使用方法:三种

方法一:内置的(模糊匹配,查询关键字search)

from rest_framework.filters import SearchFilter, OrderingFilter
查询方式http://127.0.0.1:8000/books/?search=29(模糊匹配,只要数据中有name或者price的都可以查询出)

    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['name', 'price']

方法二:第三方的(精准匹配,按照筛选器中自己需要查询的进行查询即可)

from django_filters.rest_framework import DjangoFilterBackend
http://127.0.0.1:8000/books/?name=红楼梦
 http://127.0.0.1:8000/books/?price=19&name=西游记
    filter_backends = [DjangoFilterBackend]
     filterset_fields=['name','price']   (筛选器字段)

方法三:自定义(由自己控制)

自定义过滤类中用Q来写“或”(“|”),但是url中还是用&来表示“或”

from rest_framework.filters import BaseFilterBackend
filter_queryset(self, request, queryset, view)  (重写这个方法)
重写一个文件,导入模块

 

继承APIView写过滤和排序

回顾知识:过滤

order_by()  排序
# res = models.User.objects.order_by('age') # 默认升序
# res = models.User.objects.order_by('-age') # 降序
# print(res)

继承GenericAPIView写过滤类,可以写多个

 大原则:配置多个过滤类的时候,第一个放尽量多个过滤掉数据

配置多个:执行原理

  先执行第一个过滤类:filter_queryset返回qs对象

  再执行第二个过滤类的filter_queryset,传入上一个返回的qs,过滤完返回qs对象

 

分页

只针对查询所有的接口

分页展现形式:

  web:下一页,上一页

  小程序:app:上拉加载更多

必须继承 GenericAPIView 

 先写一个文件,导入模块

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination

 PageNumberPagination分页类:

 视图类:

LimitOffsetPagination分页类:

 视图类:

 CursorPagination分页类:

视图类:

 继承GenericAPIView的视图类

from .page import CommonPageNumberPagination,CommonLimitOffsetPagination,CommonCursorPagination
class BookView(ViewSetMixin, ListAPIView):
    authentication_classes=[]
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    pagination_class =CommonCursorPagination   # 分页方式只有一种,配置一个类即可

继承APIView也要实现

class BookView(ViewSetMixin, APIView):
    authentication_classes=[]
    def list(self,request,*args,**kwargs):
        book_list=Book.objects.all()
        pagination =CommonPageNumberPagination()
        page=pagination.paginate_queryset(book_list,request)
        ser=BookSerializer(instance=page,many=True)
        return Response(ser.data)

异常处理

三大认证 视图类的方法中执行出错,都会被全局异常捕获

  认证类,认证不通过,抛异常,前端看到没有问题,只是返回了提示信息,处理了drf的异常

 drf全局异常处理,她会把drf的异常处理掉,统一返回格式,但是django原生的和python的都不会处理

无论什么异常都会返回固定格式

重写一个文件exception

视图类:

 异常类: