【Django REST framework电商项目笔记】第05章 商品列表页功能开发(下)

drf中的request和response

drf 对 Django 的 request 和 response 进行了封装
浏览器请求的 request 会被 drf 封装扩展为标准的 http request
在基本的 httpRequest 上扩展,增加了对 REST 框架灵活的请求解析和请求认证的支持

Request parsing对用户发过来的数据进行解析

data 将用户 post 过来的数据以及 files 放到 data 里面
包括所有的解析内容、文件和非文件
不仅解析 post 方法过来的内容,其他的如 put patch 都会帮我们解析

drf的过滤器

通过 drf 为我们提供的过滤功能,可以简单快速的完成过滤

GenericViewSet 继承的 GenericAPIView 中有一个可以供我们重写的方法用于我们的过滤

官方文档:使用 drf 的 filter
http://www.django-rest-framework.org/api-guide/filtering/

传统的filter 跟我们在xadmin后台中的过滤器差不多。

  • searchFilter 它的行为是search行为。
  • 排序的filter

列表页常见的三种过滤,就是列表页的传统字段精确过滤,搜索过滤,以及排序

pip install django-filter

安装之后加入已安装app的列表中。

	...
	django_filters,  # 过滤器配置

settings 中配置:

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

drf过滤器实现

from django_filters.rest_framework import DjangoFilterBackend

	...
	filter_backends = (DjangoFilterBackend,)
	filter_fields = ('name', 'shop_price') # 设置需要过滤的字段
	

模糊搜索,区间搜索
https://django-filter.readthedocs.io/en/master/

我们可以自定义我们自己的filter类,进行自定义的filter类
在 goods 目录下新建 filters.py

扫描二维码关注公众号,回复: 3457306 查看本文章
# coding: utf-8
__author__ = 'Evan'

from django_filters import rest_framework as filters
from goods.models import Goods
from django.db.models import Q


class GoodsFilter(filters.FilterSet):
    """
    商品的过滤类
    """
    pricemin = filters.NumberFilter(field_name='shop_price', lookup_expr='gt')
    pricemax = filters.NumberFilter(field_name='shop_price', lookup_expr='lt')
    top_category = filters.NumberFilter(method="top_category_filter")

    class Meta:
        model = Goods
        fields = [ 'pricemin', 'pricemax', 'is_new', 'is_hot']

返回 views 注释掉: filter_fields,这时候我们的 filter_fields 已经失效了

from rest_framework import filters
	...
    filter_backends = (DjangoFilterBackend,
                       filters.SearchFilter,
                       filters.OrderingFilter)
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')
    ordering_fields = ('sold_num', 'shop_price')

    # filter_backends = (DjangoFilterBackend,)
    # filter_fields = ('name', 'shop_price')

drf的搜索和排序

模糊查询

    # 行为: 名称中包含某字符,且字符不区分大小写
    name = filters.CharFilter(name="name", lookup_expr="icontains")

    class Meta:
        model = Goods
        fields = ['price_min', 'price_max', 'name']

配置drf里面的SearchFilter
http://www.django-rest-framework.org/api-guide/filtering/#searchfilter

from rest_framework import filters

    # 设置三大常用过滤器之DjangoFilterBackend, SearchFilter
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)

上面代码中的 filter 一定要注意不是 django 中的 filter 而是 rest_framework 中的。不然会报错

配置了 search_fields 之后配置我们的 search_fields

    # 设置我们的search字段
    search_fields = ('name', 'goods_brief', 'goods_desc')

以当前字段值开头的,等于类似于字段精确过滤。全文搜索。正则表达式搜索

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

OrderingFilter支持排序

    # 设置三大常用过滤器之DjangoFilterBackend, SearchFilter
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    # 设置排序
    ordering_fields = ('sold_num', 'add_time')

一般全文搜索,真正的模糊查询是使用 elasticSearch 来做的
重写 order 参数,来实现 url 中指定参数值

不止数据的获取,数据的提交以及后面的 login 验证等,都可以在这个接口界面进行操作,方便后端代码的调试

class GoodsAllViewSet(CacheResponseMixin,
                      mixins.ListModelMixin,
                      mixins.RetrieveModelMixin,
                      viewsets.GenericViewSet):
    """
    商品列表 ViewSet
    包括了分页,搜索,过滤,排序
    """

    '''
    # queryset = Goods.objects.all() 不设置排序会报下面的错误:
    UnorderedObjectListWarning: Pagination may yield inconsistent results 
    with an unordered object_list: <class 'goods.models.Goods'> QuerySet.
    '''
    # queryset = Goods.objects.get_queryset().order_by('id')
    throttle_classes = (AnonRateThrottle, UserRateThrottle)
    queryset = Goods.objects.all().order_by('id')
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination

    # drf的token认证机制
    # authentication_classes = (TokenAuthentication,)

    filter_backends = (DjangoFilterBackend,
                       filters.SearchFilter,
                       filters.OrderingFilter)
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')
    ordering_fields = ('sold_num', 'shop_price')

CacheResponseMixin 是设置了缓存,后面会用在一些页面的显示上,比如这里的商品列表

猜你喜欢

转载自blog.csdn.net/Yuyh131/article/details/82926223