网站建设与管理计划书在县城做同城网站怎么样
网站建设与管理计划书,在县城做同城网站怎么样,软件生成器,国外免费网站服务器文章目录 一、排序组件继承GenericAPIView使用DRF内置排序组件继承APIView编写排序 二、过滤组件继承GenericAPIView使用DRF内置过滤器实现过滤使用第三方模块django-filter实现and关系的过滤自定制过滤类排序搭配过滤使用 三、分页组件分页器一#xff1a;Pagination#xf… 文章目录 一、排序组件继承GenericAPIView使用DRF内置排序组件继承APIView编写排序 二、过滤组件继承GenericAPIView使用DRF内置过滤器实现过滤使用第三方模块django-filter实现and关系的过滤自定制过滤类排序搭配过滤使用 三、分页组件分页器一Pagination基本分页分页器二LimitOffsetPagination偏移分页分页器三CursorPagination游标分页 四、异常处理 一、排序组件 一般涉及到了查询所有才有排序对于表模型查询所有数据时需要根据某个字段进行排序时我们就可以使用到REST framework提供的内置排序组件OrderingFilter来帮助我们快速指名数据按照指定字段进行排序 使用方法
导入DRF内置排序组件from rest_framework.filters import OrderingFilter在视图类中设置类属性filter_backends[OrderingFilter] 注意这里能使用这个类属性只有是继承了GenericAPIView才行。否则无法使用 所以像继承APIView则无法使用内置过滤器REST framework会在请求的查询字符串参数中检查是否包含了ordering参数如果包含了ordering参数则按照ordering参数指明排序字段对数据集进行排序前端可以传递的ordering参数的可选字段值需要再ordering_fields中指明
继承GenericAPIView使用DRF内置排序组件 需要有表数据我这里直接沿用上一篇博客中的使用然后使用自动生成路由的方式from rest_framework.generics import ListAPIViewfrom rest_framework.viewsets import ViewSetMixinfrom rest_framework.filters import OrderingFilterfrom .serializer import BookSerializerfrom . import modelsclass BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializer配置属性filter_backends [OrderingFilter]必须指定表模型数据字段ordering_fields [price] # 可以写多个排序字段# ordering_fields [price,id]127.0.0.1:8000/api/v2/books/?ordering-price 倒序127.0.0.1:8000/api/v2/books/?orderingprice 升序继承APIView的是使用不了以上DRF提供的排序组件需要自己写自己从请求地址中取出排序规则然后自己排序 继承APIView编写排序 from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.viewsets import ViewSetMixinfrom rest_framework.mixins import ListModelMixin这里我还是沿用上面自动生成路由的方式所以需要配置ViewSetMixinclass BookView(ViewSetMixin, APIView, ListModelMixin):由于是APIView需要自己重写list方法在自动生成路由中是get:listdef list(self, request, *args, **kwargs):从地址栏中取出过滤条件print(request.query_params) # ?ordering-price,idquery_params request.query_params # {ordering:price}支持多个条件排序ordering-price,id# try:127.0.0.1:8000/api/v2/books/?ordering-price,idif , in query_params.get(ordering):query query_params.get(ordering).split(,)book_list models.Book.objects.all().order_by(*query)else:book_list models.Book.objects.all().order_by(query_params.get(ordering))ser BookSerializer(instancebook_list, manyTrue)return Response(ser.data)二、过滤组件 restful规范中要求请求地址中带过滤条件五个接口中只有查询所有接口需要过滤和排序。 其实上面排序使用的就是DRF内置过滤器因为排序本就是过滤的一种特殊情况所以这里就不在过多介绍了
继承GenericAPIView使用DRF内置过滤器实现过滤 from rest_framework.filters import SearchFilterfrom rest_framework.viewsets import ViewSetMixinfrom rest_framework.generics import ListAPIViewfrom rest_framework.filters import OrderingFilter,SearchFilterclass BookView(ViewSetMixin, GenericAPIView, ListModelMixin):queryset models.Book.objects.all()serializer_class BookSerializerSearchFilter使用的是模糊匹配filter_backends [SearchFilter]只能填写表中字段search_fields [name]search_fields [name,price] 可多字段过滤# 127.0.0.1:8000/api/v2/books/?search东# 127.0.0.1:8000/api/v2/books/?search46 因为是多字段过滤并且SearchFilter是模糊匹配所以如果多字段中有一样的东西如1都会被查到使用DRF内置过滤器它搜索结果的关系为or(或)的关系不是and关系。并且只能是使用关键字search才能使用如果我们想要用name东price66这种方式的得使用别的方法来实现 使用第三方模块django-filter实现and关系的过滤 首先需要安装第三方模块pip install django-filterfrom django_filters.rest_framework import DjangoFilterBackendfrom rest_framework.viewsets import ViewSetMixinfrom rest_framework.generics import ListAPIView使用这个第三方模块可以实现and关系并且只能是精准匹配。并且暂不支持or关系class BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializerfilter_backends [DjangoFilterBackend]filterset_fields [name, price]# 127.0.0.1:8000/api/v2/books/?name东游记price46 精准匹配但是对于django-filter来讲它是支持扩写的所以是可以支持模糊匹配具体操作自寻查找使用这个django-filter还是有局限性的无法实现or关键以及模糊匹配那么我们可以使用自定制过滤类 自定制过滤类 使用步骤1.定义一个过滤类并且继承BaseFilterBackend2.重写filter_queryset方法并且在内部完成过滤规则3.在视图类中配置自定义的过滤类from rest_framework.filters import BaseFilterBackendclass CommonFilter(BaseFilterBackend):def filter_queryset(self, request, queryset, view):queryset是之前所有数据models.Book.object.all()# request是当次请求# query_params request.query_params方式一name request.query_params.get(name,None)price request.query_params.get(price,None)res queryset.filter(name__containsname,priceprice)方式二if request.query_params.get(name):queryset queryset.filter(name__containsrequest.query_params.get(name))if request.query_params.get(price):支持链式调用queryset queryset.filter(pricerequest.query_params.get(price))return queryset # 这里返回过滤后的对象 resfrom .filters import CommonFilter class BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializer无需再配置字段了因为在自定制类中已经写好了过滤规则所以在视图类中无需配置filter_backends [CommonFilter]# 127.0.0.1:8000/api/v2/books/?name游记price666这样就实现了模糊匹配name字段并且精准匹配price字段以及查询单个字段的规则排序搭配过滤使用 from .filters import CommonFilter # 使用的是上面的自定制过滤类from rest_framework.filters import OrderingFilterclass BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializerfilter_backends [OrderingFilter,CommonFilter] # 排序加过滤从左到右依次执行ordering_fields [price,id]三、分页组件 分页只针对查询所有的接口其他四个接口不需要分页。drf内置了三个分页器对应三种分页方式内置的分页类不能直接使用需要继承定制一些参数后才能使用。一个接口只能有一种分页方式不能混合分页方式 分页器一Pagination基本分页 通过自定义Pagination类来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。 from rest_framework.pagination import PageNumberPaginationclass CommonPageNumberPagination(PageNumberPagination):page_size 3 # 默认每页显示的条数page_query_param page # 使用该关键字指定页码客户端使用page_size_query_param size # 通过该关键字可以手动指定页面显示的数据条数客户端使用max_page_size 5 # 只针对客户端手动指定页面显示的数据条数做出一个限制但不影响page_size属性。视图类 导入配置的分页类from .pagination import CommonPageNumberPaginationfrom rest_framework.viewsets import ViewSetMixinfrom rest_framework.generics import ListAPIViewfrom . import modelsfrom .serializer import BookSerializerfrom .filters import CommonFilterfrom rest_framework.filters import OrderingFilterclass BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializer注意分页方式一个接口只能使用一种所以没有加中括号pagination_class CommonPageNumberPagination使用分页并不影响排序和过滤filter_backends [OrderingFilter,CommonFilter]filterset_fields [name, price]# 127.0.0.1:8000/api/v2/books/?page2# 127.0.0.1:8000/api/v2/books/# 127.0.0.1:8000/api/v2/books/?page2size3响应时额外携带了3个参数分别是
countbook接口的数据总量next下一页的URLprevious上一页的URL如果没有上一页返回None 当然我们也可以手动指定页面显示的条数根据page_size_query_param属性值来作为关键字。 可以看到我们需要显示的是6条数据而后端只响应了5条这是因为max_page_size属性值的作用限制了客户端手动获取数据时最大返回的数据条数。 分页器二LimitOffsetPagination偏移分页 偏移分页该分页组件作用是从哪一条数据之后开始显示以及制定数据显示的条数 前端访问形式http://127.0.0.1:8080/book/?offset2limit4这表示从第3条数据之后显示4条数据 自定义分页类 from rest_framework.pagination import LimitOffsetPaginationclass CommonLimitOffsetPagination(LimitOffsetPagination):# 等同于上面的page_sizedefault_limit 2 # 如果前端没有手动指定获取的数据条数时使用该属性值limit_query_param limit # 前端通过该关键字指定数据条数每页显示条数查询的条数 例子 ?limit100 意思就是每页显示100条如果不传应用default_limit的参数offset_query_param offset # 通过该关键字指定从哪条数据之后开始获取数据偏移量 举个例子offset6limit30 意思就是从第6条开始拿30条# 等同于上面的max_page_sizemax_limit 5 # 只限制limit_query_param能够获取的最大数据条数而不影响default_limit视图类 导入配置的分页类from .pagination import CommonPageNumberPaginationclass BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializer注意分页方式一个接口只能使用一种所以没有加中括号pagination_class CommonPageNumberPagination# http://127.0.0.1:8000/api/v2/books/?limit6offset2 从第2条开始拿6条从第二条数据之后开始指定获取数据的条数使用了limit指定了获取6条但是被max_limit5给限制了所以后端只能返回2条数据如果不使用limit指定获取的数据条数那么默认使用default_limit2后端会返回2条数据。 分页器三CursorPagination游标分页
自定义分页类 from rest_framework.pagination import CursorPaginationclass CommonCursorPagination(CursorPagination):cursor_query_param cursor # 按游标查询的查询条件value值前端是不知道的只能通过后台返回page_size 2 # 每页显示多少条啊ordering id # 排序规则必须是表中的字段视图类 from .pagination import CommonCursorPaginationclass BookView(ViewSetMixin,ListAPIView):queryset models.Book.objects.all()serializer_class BookSerializer注意分页方式一个接口只能使用一种所以没有加中括号另外使用游标分页的方式后就不能再其中使用排序了因为其内部已经排好序了pagination_class CommonCursorPagination并且只能选择上一页和下一页不能指定跳转某一页但是速度快针对与特别大的数据量游标分页有优势四、异常处理 REST framework提供了异常处理我们可以自定义异常处理函数。主要是为了DRF在运行过程中发生的错误进行一个捕获然后响应友好的提示信息给前端。 自定义异常处理函数定制一个异常处理统一的返回格式 from rest_framework.views import exception_handler,Response# drf的异常处理是exception_handler处理了到那时没处理非drf的异常# 自己写个函数处理drf异常和自己的异常以后只要是出了异常都会走这里def Common_exception_handler(exc, context):# exc异常信息# context执行请求的视图、args、kwargs参数、request请求res exception_handler(exc, context)# 在此处补充自定义的异常处理if res: # 有值说明是drf的异常如果没有值说明是自己的异常# data {detail: exc.detail}detail res.data.get(detail) or drf异常请联系系统管理员return Response({code:666,message:detail})else:return Response({code:777,message:f系统异常请联系管理{str(exc)}})在配置文件中声明自定义的异常处理 REST_FRAMEWORK {EXCEPTION_HANDLER: appo1.exception.Common_exception_handler,}如果未声明会采用默认的方式如下 REST_FRAMEWORK {EXCEPTION_HANDLER: rest_framework.views.exception_handler}视图类 全局异常处理from rest_framework.exceptions import AuthenticationFailed,APIExceptionDrf中无论在三大认证还是视图类中 方法执行报错包括主动抛异常都会执行一个函数excption_exception处理异常的函数只要出了异常APIView的dispatch中就可以捕获到 执行配置文件中的EXCEPTION_HANDLER:rest_framework.views.exception_handlerclass UserView(ViewSetMixin, APIView):def create(self, request):raise Exception(你出错了)# drf默认能处理自己的异常它的异常都是继承自APIException的异常# raise AuthenticationFailed(认证失败)return Response({code:100,msg:1111})
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/86908.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!