首页 > 其他分享 >drf-排序、过滤、分页、异常处理

drf-排序、过滤、分页、异常处理

时间:2023-09-07 16:59:42浏览次数:49  
标签:http name queryset filter 过滤 排序 page drf

一、排序

只有5个接口中的查询所有,才涉及到排序,所以继承GenericViewSet,

 使用步骤:

  1. 必须写在继承:GenericAPIView 类的视图中才行

  2. 配置类属性:

  filter_backends = [OrderingFilter]

  ordering_fields=['id','user_type'] # 可以排序的字段

  3. 使用:

    http://127.0.0.1:8000/user/?ordering=user_type #按用户类型升序排

    http://127.0.0.1:8000/user/?ordering=-user_type #按用户类型降序排

    http://127.0.0.1:8000/user/?ordering=user_type,-id#先按用户类型升序排,如果用户类型一样,再按id降序排

二、过滤

1. 过滤:只针对查询所有接口,必须写在继承GenericAPIView类的视图类中  

2.使用方法:

方式一:内置的

  查询方式:http://127.0.0.1:8000/books/?search=29   模糊匹配:查询名字中有29或价格中有29都会搜出来

from .models import Book
from .serializer import BookSerializer
## 方式一:使用内置的过滤类
from rest_framework.filters import SearchFilter, OrderingFilterclass BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 方式一:内置的
    # 查询方式http://127.0.0.1:8000/books/?search=29  #模糊匹配: 只要名字中有29或价格中有29都能搜出来
    filter_backends = [SearchFilter]
    # filter_backends = [SearchFilter, OrderingFilter] #先过滤然后再排序
    search_fields = ['name', 'price'] # 按名字或价格排序

方式二:第三方的:

  需要安装一个第三方模块,django版本也要跟着换:

    pip install django == 3.2.12

    pip install django-filter

  查询方式:http://127.0.0.1:8000/books/?name=红楼梦  ---》书名是西游记的书

   http://127.0.0.1:8000/books/?price=19&name=西游记  ---》  精准匹配,价格为19并且书名是西游记的书

from .models import Book
from .serializer import BookSerializer
from django_filters.rest_framework import DjangoFilterBackend
class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # 方式二:精准匹配--》django-filter
    # 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']

方式三:自定义--完全自己控制

  1. 自己写一个过滤类,继承BaseFilterBackend类

  2. 重写filter_queryset方法

代码如下所示:

from rest_framework.filters import BaseFilterBackend
from django.db.models import Q

class MyFilter(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        # 基于queryset 进行过滤,过滤后返回即可
        # http://127.0.0.1:8000/books/?name=书   # 名字中有书的就查出来
        search_param = request.query_params.get('name')
        price = request.query_params.get('price')
        if search_param and price:
            # queryset = queryset.filter(Q(name__contains=search_param) | Q(price=price))  # qs对象的filter
            queryset = queryset.filter(name__contains=search_param,price=price)  # qs对象的filter
        return queryset

1.2 继承APIView写过滤和排序

class BookView(ViewSetMixin, APIView):
    def list(self, request, *args, **kwargs):
        # 按名字过滤
        print('asfdasdf')
        name = request.query_params.get('name')
        book_list = Book.objects.all().filter(name__contains=name)
        ser = BookSerializer(instance=book_list, many=True)
        return Response(ser.data)

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

1. 写多个,他们是从左往右,依次执行的

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

  3. 配置多个的执行原理

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

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

六、分页

1. 分页:只针对查询所有的接口

- 分页展示形式:

  web : 下一页,下一页

                     

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

必须继承:GenericAPIView

使用方式:三种分页方式 ——》drf提供的

 

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination

#方式一:
class CommonPageNumberPagination(PageNumberPagination):
    # web 用这个多
    # http://api.example.org/accounts/?page=4
    # http://api.example.org/accounts/?page=4&page_size=100
    # 重写几个类属性
    page_size = 3  # 每页显示多少条
    page_query_param = 'page'  # 指定第几页的key 值   page=4

    page_size_query_param = 'size'  # 可以指定每页显示多少条 size=300000
    max_page_size = 5  # 每页最多显示5条

#方式二:
class CommonLimitOffsetPagination(LimitOffsetPagination):
    # http://api.example.org/accounts/?limit=4   # 从开始取4条
    # http://api.example.org/accounts/?offset=4&limit=5  从第4条开始,取5条
    default_limit = 2  # 默认每页显示2条
    limit_query_param = 'limit'  # 每页显示多少条的查询条件
    offset_query_param = 'offset' # 从第几条开始取数据
    max_limit = 5   # limit最多取5条
# 方式三:
class CommonCursorPagination(CursorPagination):
    # app上用这个多
    # 只能上一页和下一页,不能指定跳转到中间的某页---》效率高,大数据量用它、
    cursor_query_param = 'cursor'  # 查询条件,用不到,需要有
    page_size = 2  # 每页显示两条
    ordering = 'id'  # 按id排序 这个必须是表中字段

views文件中:

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的都不会处理

我们要做的,无论返回什么异常,都返回固定格式

步骤:

  1. 写一个函数

# 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
from rest_framework.views import exception_handler
from rest_framework.response import Response

def common_exception(exc, context):
    # 执行一下原来的exception_handler---》它能处理drf的异常,我就不用处理了
    res = exception_handler(exc, context)
    if not res:  # 有值,说明是drf异常,它处理完了,没有值,是其他异常,我们自己处理
        return Response({'code': 999, 'msg': '非drf错误,错误信息是:%s' % str(exc)})
    else:
        return Response({'code': 888, 'msg': 'drf错误,错误信息是:' + res.data.get('detail')})

 

  2 配置文件配置
  REST_FRAMEWORK = {
  'EXCEPTION_HANDLER': 'app01.exceptions.common_exception', # 以后只要出了异常,都会走这个函数
    }

标签:http,name,queryset,filter,过滤,排序,page,drf
From: https://www.cnblogs.com/Lucky-Hua/p/17685397.html

相关文章

  • 过滤,分页,异常处理
    1过滤只针对于查询所有接口必须继承GenericAPIView#安装: pipinstalldjango==3.2.12pipinstalldjango-filter#使用方式:三种 -方式一:内置的#查询方式http://127.0.0.1:8000/books/?search=29#模糊匹配:只要名字中有29或价格中有29都能搜......
  • EXT 中文排序问题
    1.//重载Ext.data.Store.prototype.applySort函数以修复DataStore对汉字排序异常的问题2.3.//var_applySort=Ext.data.Store.prototype.applySort;4.5.//如有需要,保存原applySort函数的引用6.7.function(){//重载applySort......
  • ABP-数据过滤器(Fliter)
    过滤器文档地址ABP预定义过滤器过滤器禁用对于默认启动的过滤器,可以使用using语句临时禁用,也可全局禁用using语句临时禁用软删除过滤using(CurrentUnitOfWork.DisableAuditing(AbpDataFilters.SoftDelete)){varlist=_approvaloperaterecordsRepository.GetAll();}us......
  • 基础:归并排序
    目录简介代码与实操分解合并代码简介归并排序属于一种分治法,简单来说就是将一个大问题分解成若干类似大问题的子问题,然后分别解决,最后进行合并。一般的分治法分为如下步骤:1、分解:把一个问题分解成若干更小的类似的子问题2、解决:递归解决子问题。当子问题足够小时,按照基础情况......
  • MySQL系列之主从复制进阶——延时从库、半同步、过滤复制、GTID复制
    目录1.延时从库1.1介绍1.2为什么要有延时从1.3配置延时从库1.4延时从库应用1.4.1故障恢复思路1.4.2故障模拟及恢复2.半同步***2.1半同步复制工作原理的变化2.2配置半同步复制3.过滤复制3.1说明4.GTID复制4.1GTID引入4.2GTID介绍4.3GTID核心参数4.4......
  • drf-认证、权限、频率
    一、认证组件1.认证组件的作用一些接口,想要限制登录之后才能访问,没登录不能访问做登录认证,限制如果没有登录,不允许访问该接口2.认证类的使用:1.在auth.py中写一个类,去继承BaseAuthentication2.在这个类中重写:authenticate方法3.在authenticate完成......
  • drf 认证、权限、频率三组件
    一、认证组件判断用户是否登录,数据库是否有值1、需求:通过认证组件去认证,没有认证通过的用户不让登录。认证方式前端发来的token值与数据库进行对比2、modelsfromdjango.dbimportmodelsclassUser(models.Model):username=models.CharField(max_length=32)......
  • 如何在MySQL中对键值对表中的重复行进行多列排序?
    要在MySQL中对键值对表中的重复行进行多列排序,可以使用ORDERBY子句并指定多个列作为排序条件。以下是一个示例:假设有一个键值对表key_value,包含以下列:key_id、key_name、value。要对key_value表中的重复行按key_id和value进行排序,可以使用如下的SQL查询语句:SELECTkey_id,key_nam......
  • drf-day8
    认证组件1、登录功能写登录的时候可以使用auth提供的user表,也可以自定义写接口登录成功时,需要有一个标志,所以需要随机生成一个随机字符串,放在表中,以后只要携带这个随机字符串过来,我们就认为用户登录。视图类fromrest_framework.viewsetsimportViewSetviewset继承fromre......
  • DRF----限流、序列化、视图、条件搜索
    1.4djangorestframework(中)drf内置了很多便捷的功能,在接下来的课程中会给大家依次讲解下面的内容:快速上手请求的封装版本管理认证权限限流序列化视图条件搜索分页路由解析器 6.限流限流,限制用户访问频率,例如:用户1分钟最多访问100次......