Django restframework(实战篇)------过滤、搜索、排序、分页

Django restframework(实战篇)------过滤、搜索、排序、分页

本文转载自django-rest-framework(实战篇)——过滤、搜索、排序、分页

一、过滤

官方API向导:official API guide—Filter

django-filter 库包括一个DjangoFilterBackend类,它支持REST框架的高度可定制的字段过滤。

首先安装 django-filter ,然后将 django_filters 添加到Django的 INSTALLED_APPS 。

settings.py 加上如下配置:

REST_FRAMEWORK = {
    'DEFAULT_FIlter_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}

或者将过滤器加到单个 View 或 ViewSet 中(一般使用这种):

from django_filters.rest_framework import DjangoFilterBackend

class UserListView(mixins.ListModelMixin, viewsets.GenericViewSet):
	...
	filter_backends = (DjangoFilterBackend,)

如果要允许对某些字段进行过滤,可以使用 filter_fields 属性。

class ProductList(mixins.ListModelMixin, viewsets.GenericViewSet):
	queryset = Product.objects.all()
	serializer_class = ProductSerializer
	filter_backends = (DjangoFilterBackend,)
	filter_fields = ('category', 'in_stock')

还可以自定义过滤类,再用 filter_class 指定过滤集合类

import django_filters
from myapp.models import Product
from myapp.serializers import ProductSerializer
from rest_framework import filters
from rest_framework import generics

class ProductFilter(filters.FilterSet):
	min_price = django_filters.NumberFilter(name='price', lookup_type='gte')
	max_price = django_filters.NumberFilter(name='price', lookup_type='lte')
	# 行为:名称中包含某字符,且字符不区分大小写
	name = filters.CharFilter(name='name', lookup_expr='icontains')
	class Meta:
		model = Product
		fields = ['category', in_stock', 'min_price', 'max_price']
class ProductList(mixins.ListModelMixin, viewsets.GenericViewSet):
	queryset = Product.objects.all()
	serializer_class = ProductSerializer
	filter_backends = (filter.DjangoFilterBackend,)
	filter_class = ProductFilter

自定义查询(模糊查询)

通常我们会用到过滤两个时间段内的一些数据,当我们用django rest framework的时候,它可以根据字段filter_fields进行过滤,但是对于日期来说并不起作用,这个时候就需要我们设置重写 queryset 方法进行捕捉了:

def get_queryset(self):
	start = self.request.query_params.get('start_time', None)
	end = self.request.query_params.get('end_time', None)
	if start and stop:
		return Students.objects.filter(crated_time__gte=start).filter(created_time__lte=end)
    return Students.objects.all()
def get_queryset(self):
    """
    自定义get_queryset方法,用来条件查询queryset
    :return:
    """
    query_set = self.queryset

    record_no = self.request.query_params.get('record_no', None)
    if record_no:  # 对于病历号的模糊查询
        id_list = Registration.objects.values_list('id')
        id_list = list(id_list)
   new_list = list()
   if id_list:
        new_list = [str(i[0]) for i in id_list if record_no in str(i[0])]
        query_set = Registration.objects.filter(id__in=new_list)

   doctor = self.request.query_params.get('doctor', None)
   if doctor:  # 对于主治医生的模糊查询
       query_set = query_set.filter(doctor__real_name__icontains=doctor)

   department = self.request.query_params.get('department', None)
   if department:  # 对于门诊科室的模糊查询
       query_set = query_set.filter(department__department_name__icontains=department)

   start = self.request.query_params.get('start_time', None)
   end = self.request.query_params.get('end_time', None)
   if start and end:  # 对于挂号时间的模糊查询
       query_set = query_set.filter(regist_date__gte=start).filter(regist_date__lte=end)
   return query_set

二、搜索

官方API向导:official API guide—Searching

如果要明确指定可以对哪些字段进行搜索,可以使用 search_fields 属性,默认为可以对 serializer_class 属性指定的串行器上的任何可读字段进行搜索:

from rest_framework.filters import SearchFilter
class UserListView(mixins.ListModelMixin, viewsets.GenericViewSet):
	queryset = User.objects.all()
	serializer_class = UserSerializer
	filter_backends = (SearchFilter,)
	search_fields = ('username', 'email')

也可以使用双下划线在 Foreign Key 或 ManyToManyField 上执行相关查找:

search_fields = ('username', 'email', 'profile__profession')

默认情况下,搜索将使用不区分大小写的部分匹配。搜索参数可以包含多个搜索项,它们应该是空格和/或逗号分隔。如果使用多个搜索项,则仅当所有提供的条款匹配时,才会在列表中返回对象。默认情况下,搜索参数被命名为“search”,但这可能会被 SEARCH_PARAM 设置覆盖。

The search behavior may be restricted by prepending various characters to the search_fields。

可以通过在 search_fields 中加入一些字符来限制搜索行为,如下:

  • ‘^’:以 xx 字符串开始搜索
  • ‘=’:完全匹配
  • ‘@’:全文搜索(目前只支持Django的MySQL后端)
  • ‘$’:正则表达式搜索

三、排序

官方API向导:official API guide—Ordering

OrderingFilter 类支持简单的查询参数控制结果排序。

默认情况下,查询参数被命名为“ordering”,但这可能会被ORDERING_PARAM设置覆盖。

可以使用 ordering_fields 属性明确指定可以对哪些字段执行排序,这有助于防止意外的数据泄露,例如允许用户对密码散列字段或其他敏感数据进行排序。

如果不指定ordering_fields属性,则默认为可以对 serializer_class 属性指定的串行器上的任何可读字段进行过滤。

from rest_framework.filters import OrderingFilter
class UserListView(generic.ListAPIView):
	queryset = User.objects.all()
	serializer_class = UserSerializer
	filter_backends = (OrderingFilter,)
	ordering_fields = ('username', 'email')

使用 ordering 属性设置默认排序:

ordering = ('username',)

四、分页

可以直接在 views.py 中自定义分页规则

from rest_framework.pagination import PageNumberPagination
class StandartResultsSetPagination(PageNumberPagination):
	"""
	配置分页规则
	"""
    page_size = 12
    page_size_query_param = 'page_size'
    page_query_param = 'page'
    max_page_size = 100

应用到视图函数中:

class GoodsListViewSet(mixinx.ListModelMixin, viewsets.GenericViewSet):
	pagination_class = StandartResultsSetPagination

PageNumberPagination:此分页样式在请求查询参数中接收单个编号页面。

请求示例:GET https://api.example.org/accounts/?page=4

全局设置

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination'
}
  • PageNumberPagination类包括可以覆盖以修改分页样式的许多属性,要设置这些属性,应覆盖PageNumberPagination类,然后如上所示启用自定义分页类。
  • django_paginator_class:使用的Django Paginator类,默认是django.core.paginator.Paginator,对大部分用例是适用的。
  • page_size:数值,页面大小,默认是全局PAGE_SIZE的值。
  • page_query_param:字符串,查询参数的名称,默认是’page’。
  • page_size_query_param:字符串,请求设置页面大小的参数名称,默认是None,表示客户端可能无法控制请求的页面大小。
  • max_page_size:字符串,最大允许请求的页面大小,此属性仅在page_size_query_param也被设置时有效。
  • last_page_strings:字符串列表或者元组,默认是(‘last’,)
  • template:分页控件使用的模板的名称,可以覆盖或设置为None,默认为"rest_framework/pagination/numbers.html"

LimitOffsetPagination:查找多个数据库记录时使用的语法,客户端包括“limit”和“offset”查询参数, limit 指示要返回的最大项目数,并且相当于其他样式中的 page_size, offset 表示查询起始位置。

请求示例:GET https://api.example.org/accounts/?limit=1000&offset=400

全局设置

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
}

本文转载自django-rest-framework(实战篇)——过滤、搜索、排序、分页

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值