class Car(models.Model):
name = models.CharField(max_length=16, unique=True, verbose_name='车名')
price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='价格')
brand = models.CharField(max_length=16, verbose_name='品牌')
class Meta:
db_table = 'api_car'
verbose_name = '汽车表'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
#2.
from . import models
admin.site.register(models.Car)
#3.
class CarModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Car
fields = ['name', 'price', 'brand']
#4.
# Car的群查接口
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
#5.
url(r'^cars/$', views.CarListAPIView.as_view()),
from rest_framework.generics import ListAPIView # 第一步:drf的SearchFilter - 搜索过滤 from rest_framework.filters import SearchFilter class CarListAPIView(ListAPIView): queryset = models.Car.objects.all() serializer_class = serializers.CarModelSerializer # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS) filter_backends = [SearchFilter] # 第三步:SearchFilter过滤类依赖的过滤条件 => 接口:/cars/?search=... search_fields = ['name', 'price'] # eg:/cars/?search=1,name和price中包含1的数据都会被查询出
from rest_framework.generics import ListAPIView # 第一步:drf的OrderingFilter - 排序过滤 from rest_framework.filters import OrderingFilter class CarListAPIView(ListAPIView): queryset = models.Car.objects.all() serializer_class = serializers.CarModelSerializer # 第二步:局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS) filter_backends = [OrderingFilter] # 第三步:OrderingFilter过滤类依赖的过滤条件(为表中的字段) => 接口:/cars/?ordering=... ordering_fields = ['pk', 'price'] # eg:/cars/?ordering=-price,pk,先按price降序,如果出现price相同,再按pk升序
from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
# ?page=页码
page_query_param = 'page'
# ?page=页面 下默认一页显示的条数
page_size = 3
# ?page=页面&page_size=条数 用户自定义一页显示的条数
page_size_query_param = 'page_size'
# 用户自定义一页显示的条数最大限制:数值超过5也只显示5条
max_page_size = 5
# 2.cbv
from rest_framework.generics import ListAPIView
# 导入自定义的分页器
from . import pagenations
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyPageNumberPagination
#3.前端访问方式
第一种:拼接页数和显示条目(count表示数据总量)
第二种方式:不拼接使用自定义的(count表示数据总量)
四
# 导入模块
from rest_framework.pagination import LimitOffsetPagination
class MyLimitOffsetPagination(LimitOffsetPagination):
# ?offset=从头偏移的条数&limit=偏移位往后要显示的条数(不包括偏移的最后一位数)
limit_query_param = 'limit'
offset_query_param = 'offset'
# ?不传offset和limit默认显示前3条,只设置offset就是从偏移位往后再显示3条
default_limit = 3
# ?limit可以自定义一页显示的最大条数
max_limit = 5
# 只使用limit结合ordering可以实现排行前几或后几
# ?ordering=-price&limit=2 => 价格前2
#2.cbv
# 将刚才自定义的偏移分页器导入
from . import pahenations
from rest_framework.generics import ListAPIView
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyLimitOffsetPagination
五
# 注:必须基于排序规则下进行分页 # 1)如果接口配置了OrderingFilter过滤器,那么url中必须传ordering # 1)如果接口没有配置OrderingFilter过滤器,一定要在分页类中声明ordering按某个字段进行默认排序 from rest_framework.pagination import CursorPagination class MyCursorPagination(CursorPagination): cursor_query_param = 'cursor' page_size = 4 page_size_query_param = 'page_size' max_page_size = 5 ordering = '-pk'
#2.
from rest_framework.generics import ListAPIView
# 将刚才自定义的偏移分页器导入
from . import pahenations
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 分页组件 - 给视图类配置分页类即可 - 分页类需要自定义,继承drf提供的分页类即可
pagination_class = pagenations.MyCursorPagination
# 自定义过滤器,接口:?limit=显示的条数
class LimitFilter:
def filter_queryset(self, request, queryset, view):
# 前台固定用 ?limit=... 传递过滤参数
limit = request.query_params.get('limit')
if limit:
limit = int(limit)
return queryset[:limit]
return queryset
#2.cbv
from rest_framework.generics import ListAPIView
# 导入刚才自定义过滤器
from . import filter
class CarListAPIView(ListAPIView):
# 如果queryset没有过滤条件,就必须 .all(),不然分页会出问题
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [filter.LimitFilter]
>: pip3 install django-filter
2.使用
方式1:自定义(可拓展条件,自定义过滤条件)
#1.
# django-filter插件过滤器类
from django_filters.rest_framework.filterset import FilterSet
from . import models
# 自定义过滤字段
from django_filters import filters
class CarFilterSet(FilterSet):
min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
class Meta:
model = models.Car
fields = ['brand', 'min_price', 'max_price']
# brand是model中存在的字段,一般都是可以用于分组的字段
# min_price、max_price是自定义字段,需要自己自定义过滤条件
#2.cbv
# django-filter插件过滤器
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CarFilterSet
class CarListAPIView(ListAPIView):
queryset = models.Car.objects.all()
serializer_class = serializers.CarModelSerializer
# 局部配置 过滤类 们(全局配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [DjangoFilterBackend]
# django-filter过滤器插件使用
filter_class = CarFilterSet
# 接口:?brand=...&min_price=...&max_price=...
# eg:?brand=宝马&min_price=5&max_price=10 => 5~10间的宝马牌汽车
方式二使用系统默认的(不可拓展条件,自定义过滤条件)
# 章节 from django_filters.rest_framework import DjangoFilterBackend class ChaptersListAPIView(ListAPIView): # 提供2属性 queryset = models.CourseChapter.objects.filter(is_delete=False) serializer_class = serializers.ChapterModelSerizlizer filter_backends = [DjangoFilterBackend] #分组字段modles.py文件中的字段,此例子 ‘course为一对多外键字段 filter_fields = ['course']