当前位置: 首页 > news >正文

DRF之过滤,排序,分页

一、权限组件源码解读

1.继承了APIView

才有的---》执行流程---》dispatch中----》三大认证

APIView的dispatch  

def initial(self, request, *args, **kwargs):self.perform_authentication(request)self.check_permissions(request)self.check_throttles(request)

2 读权限:APIView的方法

self.check_permissions(request)def check_permissions(self, request):# permission_classes = [AdminPermission]# self.get_permissions()我们配置再视图类上permission_classes列表中的认证类,一个个的对象# self.get_permissions()  是  [AdminPermission(),]for permission in self.get_permissions():# 写的权限类,要重写has_permission方法# 猜permission是我们写的权限类的对象# self 是视图类的对象(BookView,PublisViwe)if not permission.has_permission(request, self): # 权限没通过self.permission_denied(request,# self.message 错误文字message=getattr(permission, 'message', None),code=getattr(permission, 'code', None))

3 读 APIView--->self.get_permissions

def get_permissions(self):return [permission() for permission in self.permission_classes]# 翻译:l=[]for permission in self.permission_classes:l.append(permission())return l

记住:

- 写的权限类,一定要写一个方法has_permission,返回True或False
    - 配置再视图类上

4.补充

视图类的方法,必须返回 4件套或drf的Response

return和raise完全不一样

视图类继承了

视图类:ViewSetMixin,ListModelMixin----》查询所有好多代码不用写----》可以自动生成路由router.register('book',BookView,'book')/book/--->get请求过来被映射了 list---》执行视图类中的list----》BookView中写了get方法,根本不会执行自动生成路由

二、认证源码分析

继承了APIView,才有的---》执行流程---》dispatch中----》三大认证

1  APIView的dispatch

self.initial(request, *args, **kwargs)def initial(self, request, *args, **kwargs):self.perform_authentication(request)self.check_permissions(request)self.check_throttles(request)

2 self.perform_authentication(request)

def perform_authentication(self, request):request.user  # 这是个方法,包装成了数据属性

3 Request类的user

@propertydef user(self):if not hasattr(self, '_user'):with wrap_attributeerrors():self._authenticate()return self._user

4 Request类的self._authenticate()

def _authenticate(self):# self.authenticators 就是你写的认证类列表---》列表推导式---》[LoginAuth(),]for authenticator in self.authenticators:try:user_auth_tuple = authenticator.authenticate(self)except exceptions.APIException:# 抛了异常被捕获了if user_auth_tuple is not None:# 如果返回了两个值,就会执行这句话# self是Request的对象self.user, self.auth = user_auth_tuplereturnself._not_authenticated()

5 Request类初始化

APIView---》dispathc的前面

总结:

1 认证类,必须写一个方法authenticate2 如果认证通过,可以返回None,也可也返回两个值,但是第一个值,尽量是当前登录用户,第二个值一般放token3 认证失败,抛异常AuthenticationFailed,继承了APIException,他能捕获

三、django中的翻译函数

只要做了国际化,会自动翻译成,当前国家的语言

from django.utils.translation import gettext_lazy as _
_('hello')

四、过滤

restful规范中
    -请求地址中带过滤条件

带过滤的接口只有:查询所有

1.内置过滤类

from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin
from .models import Book
from rest_framework.filters import SearchFilter# 内置过滤类
class BookView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookSerializer
# 支持这种搜索
# http://127.0.0.1:8000/api/v1/books/?search=红
#     search_fields = ['name']
# http://127.0.0.1:8000/api/v1/books/?search=11  只要name或price中带11都能搜出来filter_backends = [SearchFilter]search_fields = ['name']

2.第三方过滤类

from django_filters.rest_framework import DjangoFilterBackend第三方过滤类
class BookView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookSerializer# 按名字和价格精准匹配# http://127.0.0.1:8000/api/v1/books/?name=红楼梦&price=45filter_backends = [DjangoFilterBackend]filterset_fields = ['name', 'price']

3.自定义过滤类

views:

from .filter import MyFilter自定义过滤类
class BookView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookSerializer# 返回的数据,就是过滤后的数据# http://127.0.0.1:8000/api/v1/books/?name=三国演义&price=25   按名字或价格filter_backends = [MyFilter]filterset_fields = ['name', 'price']

 filter:

from rest_framework import filters
from django.db.models import Qclass MyFilter(filters.BaseFilterBackend):def filter_queryset(self, request, queryset, view):price = request.query_params.get('price')name = request.query_params.get('name')# 返回的数据,就是过滤后的数据# http://127.0.0.1:8000/api/v1/books/?price=44&name=红楼梦# 按名字或价格queryset = queryset.filter(Q(name=name) | Q(price=price))return queryset

小练习:区间过滤

取出价格在100-200元之间的书

views:

# 自定义过滤价格在一百到两百之间的图书
from .filter import BookFilterSet
from rest_framework.filters import SearchFilterclass BookView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookSerializerfilter_backends = [BookFilterSet]search_fields = ['price']

filter:

# 自定义过滤价格在一百到两百之间的图书from rest_framework import filters
from .models import Bookclass BookFilterSet(filters.BaseFilterBackend):def filter_queryset(self, request, queryset, view):price = request.query_params.get('price')min_price = request.query_params.get('min_price')max_price = request.query_params.get('max_price')queryset = queryset.filter(price__gt=min_price, price__lt=max_price)return queryset

过滤和排序可以一起使用:

例:

url:

from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import SimpleRouter
from app01 import viewsrouter = SimpleRouter()
# 图书路由
# router.register('books', views.BookView, 'book')
# 出版社路由
# router.register('publishes', views.PublishView, 'publish')urlpatterns = [path('admin/', admin.site.urls),path('api/v1/', include(router.urls)),
]

views:

from .models import Publish
from .serializer import PublishSerializer
from rest_framework.filters import OrderingFilter
from .page import PublishPageNumberPaginationclass PublishView(GenericViewSet, ListModelMixin):queryset = Publish.objects.all()serializer_class = PublishSerializerfilter_backends = [SearchFilter, OrderingFilter]search_fields = ['title', 'addr']ordering_fields = ['id']pagination_class = PublishPageNumberPagination

page:

class PublishPageNumberPagination(PageNumberPagination):page_size = 1page_size_query_param = 'page_size'page_query_param = 'page'max_page_size = 5

五排序

restful规范中
    -请求地址中带过滤条件

排序功能的接口:查询所有

排序
from rest_framework.filters import OrderingFilterclass BookView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookSerializer# 排序类# http://127.0.0.1:8000/api/v1/books/?ordering=pricefilter_backends = [OrderingFilter]ordering_fields = ['price']

六 分页

查询所有接口,过滤和排序了,但是实际上,这个接口,都需要有分页功能

-分页的展现形式
        web:下一页点解
        app,小程序:下滑下一页
    -接口都一样,要支持分页

drf提供给咱们,三种分页方式:


1.基本分页(用的较多)

views:

class BookView(GenericViewSet, ListModelMixin):queryset = Book.objects.all()serializer_class = BookSerializer# 基本分页# http://127.0.0.1:8000/api/v1/books/?page=2&page_size=3pagination_class = MyPageNumberPagination  # 基本分页

 page:

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination# 基本分页
class MyPageNumberPagination(PageNumberPagination):# 重新几个类属性 :4个page_size = 2  # 每页的显示条数page_query_param = 'page'  # page=4表示第4页page_size_query_param = 'page_size'  # page=4&page_size=5 表示查询第4页,每页显示5条max_page_size = 5  # 每页最大显示多少条


2.偏移分页

view:

 # 偏移分页# http://127.0.0.1:8000/api/v1/books/?limit=2&offset=5pagination_class = MYLimitOffsetPagination

page:

# 偏移分页
class MYLimitOffsetPagination(LimitOffsetPagination):# 重写几个类属性:4个default_limit = 2  # 每页显示多少条limit_query_param = 'limit'  # limit=3 这一页取三条offset_query_param = 'offset'  # 偏移量是多少 offset=3max_limit = 5  # 最多取5条


3.游标分页

views:

    # 游标分页# http://127.0.0.1:8000/api/v1/books/?ordering=idpagination_class = MyCursorPagination


page:

# 游标分页
class MyCursorPagination(CursorPagination):# 重写三个类属性cursor_query_param = 'cursor'  # 查询参数其实用不到page_size = 2  # 每页显示多少条ordering = 'id'  # 必须是要分页的数据表中的字段,一般按id来分

http://www.lryc.cn/news/89590.html

相关文章:

  • 我的Redis学习,共写了14篇博客文章
  • mPython软件使用指南
  • 龙芯2K1000实战开发-系统配置详解
  • 【一起撸个DL框架】5 实现:自适应线性单元
  • 开箱即用的工具函数库xijs更新指南(v1.2.6)
  • 【Netty】ChannelPipeline源码分析(五)
  • 并行计算技术解密:MPI和OpenMP的学习和应用指南
  • 什么是自动化测试框架?我们该如何搭建自动化测试框架?
  • Debezium报错处理系列之六十七:TopicAuthorizationException: Not authorized to access topics
  • javaWebssh中小学课件资源系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计
  • MySQL高级查询操作
  • Day53【动态规划】1143.最长公共子序列、1035.不相交的线、53.最大子序和
  • Three.js--》实现3d地球模型展示
  • <SQL>《SQL命令(含例句)精心整理版(6)》
  • 信息系统建设和服务能力评估证书CS
  • vue3引入路由
  • 前后端联调跨域问题
  • day11 - 手写数字笔迹细化
  • C++ QT QDBus基操
  • STM32的SPI外设
  • VMWare ESXI6.7创建虚拟机
  • TensorFlow 1.x学习(系列二 :4):自实现线性回归
  • Openwrt折腾记6-网络摄像头
  • C++判断大端小端
  • K8S RBAC之Kubeconfig设置用户权限,不同的用户访问不同的namespace
  • CodeForces..学习读书吧.[简单].[条件判断].[找最小值]
  • 灵活使用Postman环境变量和全局变量,提高接口测试效率!
  • Springboot+Vue3 整合海康获取视频流并展示
  • Linux——进程退出
  • 组长给组员派活,把组长自己的需求和要改的bug派给组员,合理吗?