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

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

时间:2023-09-10 10:33:43浏览次数:36  
标签:size search name price 过滤 query 排序 page drf

session的执行流程

写一个登录接口----->保存用户的登录状态
	-获取到用户名,密码
    -使用request.session["username"] = 用户名、或者request.session["pk"] = pk值
    -签发阶段做了三件事:
    	-1、生成一个随机的字符串
        -2、在django_session表中保存
        	-session_key:随机字符串
            -session_data:加密后的数据
            -expire_data:截止到14天后到期自动删除
        -3、把随机的字符串以cookie形式返回给前端(存在浏览器的cookie中)
    -认证阶段:
    	-1、取出在cookie中session_id对应的随机字符串
        -2、通过这个随机字符串在django_session表中查询,如果查询的到说明该用户是在登录状态
        -3、将session_data的数据放到request_session中

过滤

只针对于,查询所有接口,必须要继承 GenericAPIView

安装:
    -pip install django==3.2.12
    -pip install django-filter

使用方法

方法一:内置的、模糊匹配
from rest_framework.filters import SearchFilter
    # 重写属性
    filter_backends = [SearchFilter, OrderingFilter]
    search_fields = ['name', 'price']
    # 查询方式
    http://127.0.0.1:8000/text/?search=水 # 就可以查出来与水相关的书籍
            
方式二:第三方的、精准匹配而且支持"&"
from django_filters.rest_framework import DjangoFilterBackend
	# 重写属性
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["name", "price"]
    # 查询方式:
    http://127.0.0.1:8000/text/?name=红楼梦 or
    http://127.0.0.1:8000/text/?name=红楼梦&price=123
            
方式三:自定义方法
    # 重写属性
    filter_backends = [BookFilter]
    # 查询方式
	http://127.0.0.1:8000/books/?price=123&name=西游记

自定义过滤方法

from rest_framework.filters import BaseFilterBackend


class BookFilter(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        search_parm = request.query_params.get("name")
        search_price = request.query_params.get("price")
        print("++++", search_parm, "-----", search_price)
        if search_parm and search_price:
            print("走到这里了")
            queryset = queryset.filter(name__contains=search_parm, price=search_price)
            return queryset

继承ViewSet实现的视图

class BookText(ViewSet):
    def list(self, request):
        # 获取到前端传入的筛选条件
        search_parm = request.query_params.get("name")
        # 通过__contains找到与我这个name字段是否有我search_parm的值,如果有返回这个值的对象
        book_obj = Book.objects.all().filter(name__contains=search_parm)

        serializers = BookSerializers(instance=book_obj, many=True)

        return Response(serializers.data)

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

# 写多个,他们是从左往右,依次执行
# 大原则,配置多个过滤类的时候,第一个放尽量多个过滤掉数据
# 配置多个:执行原理
	-先执行第一个过滤类的:filter_queryset返回qs对象
    -再执行第二个过滤类的filter_queryset,传入上一个返回的qs,过滤完返回qs对象

过滤小结

1、内置的:from rest_framework.filters import SearchFilter
	-重写属性:
    	-filter_backends、search_fields
2、第三方的:from django_filters.rest_framework import DjangoFilterBackend
	-重写属性:
    	-filter_backends、filterset_fields
3、自定义的:from rest_framework.filters import BaseFilterBackend
	-自己写一个类继承BaseFilterBackend,可以按照自己的想法,指定想要过滤的字段
    -重写属性:
    	-filter_backends

分类

只针对于查询所有接口:
	-分页展示形式
    	web:上一页,下一页
        小程序:上拉加载更多
        
必须继承 GenericAPIView

三种分页方式------->drf提供的
导入模块:
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination

使用PageNumberPagination分页类

class ComePageNumber(PageNumberPagination):
    # 重写参数
    page_size = 3  # 每页展示3条
    page_query_parm = "page"  # 索引前缀
    page_size_query_param = "size"  # # 可以指定每页显示多少条 eg:size=300000
    max_page_size = 4

前端展示

{
    "count": 4, # 总数据量
    "next": "http://127.0.0.1:8000/text/?page=2", # 下一页
    "previous": null, # 前一页
    "results": [
        {
            "id": 1,
            "name": "西游记",
            "price": "123"
        },
        {
            "id": 2,
            "name": "红楼梦",
            "price": "234"
        },
        {
            "id": 3,
            "name": "红楼梦",
            "price": "345"
        }
    ]
}

使用LimitOffsetPagination分页类

class ComeLimit(LimitOffsetPagination):
    default_limit = 2  # 默认每页显示2条
    limit_query_param = "limit"  # 每页显示多少条的查询
    offset_query_param = "offset"  # 从第几条数据开始
    max_limit = 5  # limit最多取5条

前端展示

URLs:
	http://127.0.0.1:8000/text/?limit=3&offset=3&size=2
{
    "count": 4,
    "next": null,
    "previous": "http://127.0.0.1:8000/text/?limit=3&size=2",
    "results": [
        {
            "id": 4,
            "name": "水浒传",
            "price": "456"
        }
    ]
}

使用CursorPagination分页类

class ComeCursor(CursorPagination):
    cursor_query_param = "cursor"
    page_size = 2
    ordering = "id"

前端展示

URLs:
	http://127.0.0.1:8000/text/?cursor=cj0xJnA9Mw%3D%3D
{
    "next": "http://127.0.0.1:8000/text/?cursor=cD0y",
    "previous": null,
    "results": [
        {
            "id": 1,
            "name": "西游记",
            "price": "123"
        },
        {
            "id": 2,
            "name": "红楼梦",
            "price": "234"
        }
    ]
}

分页类总结

继承PageNumberPagination分页类:
	-重写属性:
        -page_size = 4 # 每页显示4条
        -page_query_parm = "page"  # 索引前缀
        -page_size_query_param = "size" # 可以指定每页显示多少条 eg:size=300
        -max_page_size = 4

继承LimitOffsetPagination分页类:
	-重写属性:
        -default_limit = 2  # 默认每页显示2条
        -limit_query_param = "limit"  # 每页显示多少条的查询
        -offset_query_param = "offset"  # 从第几条数据开始
        -max_limit = 5  # limit最多取5条
        
继承CursorPagination分页类:
	-重写属性:
        -cursor_query_param = "cursor"
        -page_size = 2
        -ordering = "id"
        
PageNumberPagination适用于传统的分页需求,简单易用,但在大数据量和实时数据更新的场景下性能可能有限。

LimitOffsetPagination适用于快速定位到某个位置的场景,但在大数据量和实时数据更新的场景下性能可能有限。

CursorPagination适用于大数据量和实时数据更新的场景,可以灵活定制排序方式,但需要客户端保存和传递游标信息

继承GenericAPIView实现的视图

class Text(ViewSetMixin, ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializers
    ################分页类################
    pagination_class = ComeCursor 
    pagination_class = ComeLimit
    pagination_class = ComePageNumber
    # 三者选其一即可,前提是三个分页类都写好了
    #####################################
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["name", "price"]

继承APIView实现


异常处理

# drf中的所有异常都会被全局捕捉到
	-认证类,认证不通过抛出异常,会被全局捕捉到,所以前端不会崩掉,只会得到错误信息
    
drf全局异常处理,他会把drf的异常处理掉,统一返回格式,但是django原生的和python的都不会处理

# 我们要做的就是无论是Python还是Django异常我们都可以捕捉到,统一格式返回

新建一个exception文件

1、写一个方法;
from rest_framework.views import exception_handler

from rest_framework.response import Response


    def my_exception(exc, context):
        exc = exception_handler(exc, context)  # 返回结果为None
        if not exc: # 如果不为None就除drf的异常
            return Response({'code': 1000, 'msg': '非drf错误,错误信息是:%s' % str(exc)})
        else: # 否则就是drf的异常
            return Response({'code': 1000, 'msg': 'drf错误,错误信息是:' + exc.data.get('detail')})

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

补充

1 DateField、DateTimeField
    -auto_now_add=True    # 创建数据时自动添加当前时间
    -auto_now=True           # 每次操作数据时更新为当前时间

作业

# 1 DateTimeField的两个字段属性有什么用,如果没做国际化,存的时间什么样,查出来打印出来的时间是什么样的?(做过国际化和没做的区别)

# 2 继承APIView实现3种分页

page = self.paginate_queryset(queryset) # 使用所有数据分页
# paginate=CommonCursorPagination()
# page=paginate.paginate_queryset(queryset, self.request, view=self)
if page is not None:
     serializer = BookSerializer(page, many=True) #序列化分页后的数据
     return self.get_paginated_response(serializer.data)


# 3 三种方式实现过滤
# 4 继承GenericAPIView写三种分页
# 5 写一个全局异常处理,以后无论出什么错,都返回固定格式

DateField、DateTimeField的两个字段属性有什么用,如果没做国际化,存的时间什么样,查出来打印出来的时间是什么样的?(做过国际化和没做的区别)

DateField和DateTimeField是Django模型中用于存储日期和日期时间的字段属性。

DateField:用于存储日期,只包含年、月、日的信息。
DateTimeField:用于存储日期时间,包含年、月、日、时、分、秒的信息。
如果没有进行国际化处理,存储的时间会按照数据库的时区进行存储,通常是UTC时间(协调世界时)。当从数据库中查询出来并打印时,时间仍然会以UTC时间的格式显示。

标签:size,search,name,price,过滤,query,排序,page,drf
From: https://www.cnblogs.com/chao0308/p/17690859.html

相关文章

  • drf- 三大认证、排序
    三大认证组件登录认证我们可以使用auth自带的User表,也可以选择自定义表.写登录接口,登录成功要有标志,生成一个随机的字符串,放到表中,以后只要携带这个字符串就可以登录成功。视图层方法一:classUserView(GenericViewSet):queryset=models.UserInfo.objects.all()......
  • 记一次SpringBoot Filter的过滤器被重复执行问题
    记一次SpringBootFilter的过滤器被重复执行问题debug发现过滤器执行两次,后来定位到WebFilter和Component注解导致多次扫描,而这次需要用到WebFilter,所以注掉了Component@Order(0)//@Component@WebFilter(urlPatterns={"/*"})@ConditionalOnProperty(name="color.trace.s......
  • es排序
    ......
  • C#希尔排序算法
    前言希尔排序简单的来说就是一种改进的插入排序算法,它通过将待排序的元素分成若干个子序列,然后对每个子序列进行插入排序,最终逐步缩小子序列的间隔,直到整个序列变得有序。希尔排序的主要思想是通过插入排序的优势,减小逆序对的距离,从而提高排序效率。希尔排序实现原理首先要确......
  • 排序总结 链表
    排序总结时间复杂度空间复杂度是否能有稳定性选择O(N*N)O(1)×冒泡O(N*N)O(1)✔️插入O(N*N)O(1)✔️归并O(N*logN)O(N)✔️快排(一般指3.0)O(N*logN)O(N*logN)×堆O(N*logN)O(1)×基数排序作为不基于比较的排序,有稳定性基础类型的排序一般排序用快排,因为其时间复杂度常数项更小,需要保持......
  • 解析排序算法:十大排序方法的工作原理与性能比较
    当我们面临对数据进行排序的任务时,计算机科学家们开发了多种排序算法来满足不同的需求。这些排序算法各具特点,适用于不同规模和类型的数据集。在本文中,我们将介绍十大常见的排序算法,并讨论它们的工作原理、时间复杂度以及适用场景。1.冒泡排序(BubbleSort)冒泡排序是最简单的排序算......
  • LeetCode -- 207. 课程表 (拓扑排序)
     经典拓扑排序的应用,用拓扑排序的算法看看原图中是否有一个合法的拓扑序。classSolution{public:conststaticintN=2010,M=5010;inth[N],e[M],ne[M],idx;intd[N],q[N];voidadd(inta,intb){e[idx]=b,ne[idx]=h[a],h[......
  • 接口文档、jwt介绍和构成、jwt签发和认证、base64编码、drf-jwt编码、drf-jwt使用
    接口文档作为后端,接口写好了,需要编写接口文档作为前端,需要使用后端写的接口(移动端、web桌面端),可以照着接口文档写接口文档的展现形式:1.word、md,写好传到公司的某个平台===》前端可以下载使用2.自动生成接口文档===》后端通过配置===》把所写的接口都自动生成===》......
  • 2039:【例5.6】冒泡排序
    2039:【例5.6】冒泡排序时间限制:1000ms      内存限制:65536KB提交数:51543   通过数:28200【题目描述】编程输入n(1≤n≤20)(1≤n≤20)个小于10001000非负整数,然后自动按从大到小的顺序输出。(冒泡排序)【输入】第一行,数的个数n;第二行,n个非负整数。......
  • 接口文档,jwt介绍和构成,jwt签发与认证,base64编码,drf-jwt使用,django-rest-framewor
    1接口文档#作为后端,接口写好了#作为前端,需要使用我们写的接口(移动端,web,桌面端)#后端需要写接口文档#接口文档的展现形式: 1word,md,写好传到公司的某个平台---》前端可以下载2自动生成接口文档---》后端通过配置--》把所写的接口都自动生成---》地址--》访问......