您现在的位置是: 网站首页 >Django >Vue+Django REST framework前后端分离生鲜电商 Django
【Vue+DRF生鲜电商】09.使用DRF的filter过滤商品列表
admin2019年4月24日 17:48 【Django | Python | Vue 】 3085人已围观
Vue+Django REST framework前后端分离生鲜电商简介 Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。 Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ; Django版本:2.2、djangorestframework:3.9.2。 前端Vue模板可以直接联系我拿。
### DRF过滤商品列表 `GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet)`继承的`viewsets.GenericViewSet`(`GenericViewSet(ViewSetMixin, generics.GenericAPIView)`)继承的`GenericAPIView(views.APIView)`提供了一个`get_queryset()`方法,可以通过这个方法,进行过滤 ```python # 源码内容 def get_queryset(self): queryset = self.queryset if isinstance(queryset, QuerySet): # Ensure queryset is re-evaluated on each request. queryset = queryset.all() return queryset ``` #### 使用get_queryset查询函数 修改 views.py 中的视图 ```python class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 显示商品列表 """ queryset = Goods.objects.all() # 使用get_queryset函数,依赖queryset的值 serializer_class = GoodsSerializer pagination_class = GoodsPagination def get_queryset(self): return Goods.objects.filter(shop_price__gt=120) ``` 筛选商店价格大于120元的数据,刷新 http://127.0.0.1:8000/goods/ ![BLOG_20190424_175203_98](/media/blog/images/2019/04/BLOG_20190424_175203_98.png "博客图集BLOG_20190424_175203_98.png") 可以看到总的数量已经发生变化。 #### 获取url的参数request.query_params,传递价格区间 参考 https://www.django-rest-framework.org/api-guide/requests/#query_params `request.query_params`是`request.GET`的更正确的同义词。 为了使代码更清晰,建议使用**`request.query_params`**而不是Django的标准request.GET。这样做将有助于保持代码库更加正确和明显——任何HTTP方法类型都可能包含查询参数,而不仅仅是GET请求。 修改 views.py 增加过滤参数 ```python class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 显示商品列表 """ queryset = Goods.objects.all() # 使用get_queryset函数,依赖queryset的值 serializer_class = GoodsSerializer pagination_class = GoodsPagination def get_queryset(self): queryset = self.queryset # 传递价格区间的参数 price_min = self.request.query_params.get('price_min') if price_min: queryset = queryset.filter(shop_price__gte=price_min) return queryset ``` 现在访问 http://127.0.0.1:8000/goods/?price_min=160 指定过滤条件,最小价格为160 ![BLOG_20190424_175142_69](/media/blog/images/2019/04/BLOG_20190424_175142_69.png "博客图集BLOG_20190424_175142_69.png") 但是如果过滤条件很多的情况,就需要加入很多的筛选,也就是`get_queryset`函数需要获取每个参数及其值,然后在查询集进行过滤,比较麻烦 #### 使用DjangoFilterBackend 参考 https://www.django-rest-framework.org/api-guide/filtering/#djangofilterbackend `django-filter`库包含一个`DjangoFilterBackend`类,它支持REST框架的高度可定制字段过滤。 要使用`DjangoFilterBackend`,首先安装`pip install django-filter`。然后将`django_filters`添加到Django的`INSTALLED_APPS` ```python INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 添加drf应用 'rest_framework', 'django_filters', # 注册富文本编辑器ckeditor 'ckeditor', # 注册富文本上传图片ckeditor_uploader 'ckeditor_uploader', 'users.apps.UsersConfig', 'goods.apps.GoodsConfig', 'trade.apps.TradeConfig', 'user_operation.apps.UserOperationConfig' ] ``` 修改 views.py 增加商品列表的过滤器 ```python from django_filters.rest_framework import DjangoFilterBackend class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 显示商品列表 """ queryset = Goods.objects.all() # 使用get_queryset函数,依赖queryset的值 serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = (DjangoFilterBackend,) # 将过滤器后端添加到单个视图或视图集 filterset_fields = ('name', 'goods_desc', ) ``` 当搜索一个name完整名称显示如下,这时url为 http://127.0.0.1:8000/goods/?name=%E6%96%B0%E9%B2%9C%E6%B0%B4%E6%9E%9C%E7%94%9C%E8%9C%9C%E9%A6%99%E8%84%86%E5%8D%95%E6%9E%9C%E7%BA%A6800%E5%85%8B&goods_desc= : ![BLOG_20190424_175130_18](/media/blog/images/2019/04/BLOG_20190424_175130_18.png "博客图集BLOG_20190424_175130_18.png") 但是,如果要模糊搜索,这时候url为 http://127.0.0.1:8000/goods/?name=%E6%B0%B4%E6%9E%9C&goods_desc= ![BLOG_20190424_175114_71](/media/blog/images/2019/04/BLOG_20190424_175114_71.png "博客图集BLOG_20190424_175114_71.png") 这一看到,是过滤不出结果的,因为这是一个 **等式** 的匹配 可以查看官方文档 https://django-filter.readthedocs.io/en/master/guide/rest_framework.html 如何自定义filter,可以参考 https://django-filter.readthedocs.io/en/master/guide/rest_framework.html#adding-a-filterset-with-filterset-class 首先,在应用下创建 filters.py 文件,用于放置所有的filter ![BLOG_20190424_175058_56](/media/blog/images/2019/04/BLOG_20190424_175058_56.png "博客图集BLOG_20190424_175058_56.png") 修改添加以下内容 ```python # filters.py from django_filters import rest_framework as filters from .models import Goods class GoodsFilter(filters.FilterSet): """ 商品的过滤类 """ name = filters.CharFilter(field_name='name', lookup_expr='contains') # 包含关系,模糊匹配 goods_desc = filters.CharFilter(field_name='name', lookup_expr='contains') min_price = filters.NumberFilter(field_name="shop_price", lookup_expr='gte') # 自定义字段 max_price = filters.NumberFilter(field_name="shop_price", lookup_expr='lte') class Meta: model = Goods fields = ['name', 'goods_desc', 'min_price', 'max_price'] ``` 例如上方的`field_name='name', lookup_expr='contains'`就类似于Django中`queryset.filter(name__contains=xxx)`,`field_name`需和模型中的字段保持一致,而前面的字段就是url中的参数。`Meta`需要指定操作的模型名以及对应的字段。 修改 views.py ,添加自定义过滤类`filterset_class = GoodsFilter` ```python from django_filters.rest_framework import DjangoFilterBackend from .filters import GoodsFilter class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 显示商品列表 """ queryset = Goods.objects.all() # 使用get_queryset函数,依赖queryset的值 serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = (DjangoFilterBackend,) # 将过滤器后端添加到单个视图或视图集 filterset_class = GoodsFilter ``` ![BLOG_20190424_175036_17](/media/blog/images/2019/04/BLOG_20190424_175036_17.png "博客图集BLOG_20190424_175036_17.png") 输入字段进行过滤,这时候url为: http://127.0.0.1:8000/goods/?name=%E6%B0%B4%E6%9E%9C&goods_desc=&min_price=150&max_price=180 #### 使用SearchFilter 参考: https://www.django-rest-framework.org/api-guide/filtering/#searchfilter 搜索最适合模糊匹配 `SearchFilter`类支持简单的基于查询参数的搜索,并且基于Django管理员的搜索功能。 `search_fields`属性应该是模型中文本类型字段的名称列表,例如CharField或TextField。 修改 views.py ```python from rest_framework import viewsets, filters from django_filters.rest_framework import DjangoFilterBackend class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 显示商品列表 """ queryset = Goods.objects.all() # 使用get_queryset函数,依赖queryset的值 serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = (DjangoFilterBackend, filters.SearchFilter,) # 将过滤器后端添加到单个视图或视图集 filterset_class = GoodsFilter search_fields = ('name', 'goods_desc') # 搜索字段 ``` 刷新页面,输入搜索字段(模糊匹配) ![BLOG_20190424_175026_53](/media/blog/images/2019/04/BLOG_20190424_175026_53.png "博客图集BLOG_20190424_175026_53.png") 这时候url为: http://127.0.0.1:8000/goods/?search=%E6%B0%B4%E6%9E%9C 可以搜索对应的内容。 也可以对一个外键或`ManyToManyField`执行相关的查找,使用查找API双下划线表示法: ```python search_fields = ('name', 'goods_desc', 'category__name') # 最后表示搜索外键分类名称 ``` 默认情况下,搜索将使用不区分大小写的部分匹配。搜索参数可以包含多个搜索项,这些搜索项应该用空格和/或逗号分隔。如果使用多个搜索项,则仅当所提供的所有项都匹配时,才会在列表中返回对象。 搜索行为可能受到search_fields前置各种字符的限制。 - `^`:以搜索的文本开始。 - `=`:精确匹配。 - `@`:全文搜索。(目前只支持Django的MySQL后端)。 - `$`:正则表达式搜索。 #### 使用OrderingFilter 参考: https://www.django-rest-framework.org/api-guide/filtering/#orderingfilter `OrderingFilter`类支持简单的查询参数控制的结果排序。 默认情况下,查询参数名为`ordered`,但是可以通过`ORDERING_PARAM`设置覆盖该参数。 修改 views.py ```python class GoodsListViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): """ 显示商品列表,分页、过滤、搜索、排序 """ queryset = Goods.objects.all() # 使用get_queryset函数,依赖queryset的值 serializer_class = GoodsSerializer pagination_class = GoodsPagination filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter,) # 将过滤器后端添加到单个视图或视图集 filterset_class = GoodsFilter search_fields = ('name', 'goods_desc', 'category__name') # 搜索字段 ordering_fields = ('click_num', 'sold_num', 'shop_price') # 排序 ``` 访问页面点击任意排序 ![BLOG_20190424_174958_52](/media/blog/images/2019/04/BLOG_20190424_174958_52.png "博客图集BLOG_20190424_174958_52.png") 这时候url为: http://127.0.0.1:8000/goods/?ordering=shop_price 如果是倒排序,则url为: http://127.0.0.1:8000/goods/?ordering=-shop_price 当然,也可以根据过滤后的内容进行排序 ![BLOG_20190424_174945_29](/media/blog/images/2019/04/BLOG_20190424_174945_29.png "博客图集BLOG_20190424_174945_29.png") 这时候url为: http://127.0.0.1:8000/goods/?goods_desc=&max_price=&min_price=&name=%E6%B0%B4%E6%9E%9C&ordering=-shop_price
很赞哦! (1)
相关文章
文章交流
- emoji
当前用户
未登录,点击 登录专题目录
- 【Vue+DRF生鲜电商】01.课程结构介绍,开发环境搭建
- 【Vue+DRF生鲜电商】02.设置users、goods、trade、user_operation数据库并导入原始数据
- 【Vue+DRF生鲜电商】03.Restful API基础
- 【Vue+DRF生鲜电商】04.Vue项目结构介绍
- 【Vue+DRF生鲜电商】05.商品列表序列化普通方法
- 【Vue+DRF生鲜电商】06.DRF环境配置,使用Serializer类序列化商品列表
- 【Vue+DRF生鲜电商】07.序列化商品分页功能
- 【Vue+DRF生鲜电商】08.ViewSets & Routers显示商品列表
- 【Vue+DRF生鲜电商】09.使用DRF的filter过滤商品列表
- 【Vue+DRF生鲜电商】10.商品分类层级获取,Vue跨域请求商品分类
- 【Vue+DRF生鲜电商】11.Vue展示左侧分类、面包屑、排序、商品列表、分页
- 【Vue+DRF生鲜电商】12.用户登录之DRF Token认证登录原理和使用方法
- 【Vue+DRF生鲜电商】13.JWT用户认证原理配置,Vue登录接口调试
- 【Vue+DRF生鲜电商】14.用户注册发送短信验证码、登录字段验证
- 【Vue+DRF生鲜电商】15.用户注册使用信号量实现密码加密
- 【Vue+DRF生鲜电商】16.Vue中注册、退出功能交互
- 【Vue+DRF生鲜电商】17.DRF实现商品详情及热卖商品接口,Vue中显示商品详情和热卖
- 【Vue+DRF生鲜电商】18.用户收藏、取消收藏商品接口实现
- 【Vue+DRF生鲜电商】19.用户添加、删除收藏权限处理,根据商品id显示收藏,在Vue中实现收藏功能
- 【Vue+DRF生鲜电商】20.使用DRF自动生成文档的功能
- 【Vue+DRF生鲜电商】21.用户中心个人资料的展示,并在Vue中实现个人资料更新
- 【Vue+DRF生鲜电商】22.个人中心显示用户收藏功能,对收藏进行删除
- 【Vue+DRF生鲜电商】23.个人中心用户留言功能
- 【Vue+DRF生鲜电商】24.用户收货地址功能
- 【Vue+DRF生鲜电商】25.商品添加购物车接口功能,Vue和购物车联调
- 【Vue+DRF生鲜电商】26.使用Pycharm远程代码调试服务器Django代码
- 【Vue+DRF生鲜电商】26.订单接口功能,Vue和订单接口联调
- 【Vue+DRF生鲜电商】27.支付宝公钥,私钥,沙箱环境配置
- 【Vue+DRF生鲜电商】28.支付宝支付接口类解读,支付逻辑编辑
- 【Vue+DRF生鲜电商】29.线上服务支付宝接口和Vue联调,Django代理Vue运行
- 【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能
- 【Vue+DRF生鲜电商】31.首页商品按分类显示推荐功能
- 【Vue+DRF生鲜电商】32.商品操作后计数更改,热搜榜关键字功能实现
- 【Vue+DRF生鲜电商】33.数据缓存、接口访问限速功能
- 【Vue+DRF生鲜电商】34.第三方登录(微博、qq和微信)之微博登录登录测试
- 【Vue+DRF生鲜电商】35.使用social-app-django集成第三方登录