(PS:转载自http://www.cnblogs.com/derek1184405959/p/8810591.html  有修改)

一、drf的过滤

(1)添加到app里面

  1. INSTALLED_APPS = [
  2. 'django_filters',
  3. ]

(2)新建filter.py

自定义一个过滤器

  1. # goods/filters.py
  2.  
  3. import django_filters
  4.  
  5. from .models import Goods
  6.  
  7. class GoodsFilter(django_filters.rest_framework.FilterSet):
  8. '''
  9. 商品过滤的类
  10. '''
  11. #两个参数,name是要过滤的字段,lookup是执行的行为,‘小与等于本店价格’。
  12. #注意,这里我用的django-filter是2.0.0,因此跟视频教程中不一样,所以这里的
  13. #name="shop_price"要改为field_name="shop_price",不然报错
  14. price_min = django_filters.NumberFilter(name="shop_price", lookup_expr='gte')
  15. price_max = django_filters.NumberFilter(name="shop_price", lookup_expr='lte')
  16.  
  17. class Meta:
  18. model = Goods
  19. fields = ['price_min', 'price_max']

(3)views.py

  1. from .filters import GoodsFilter
  2. from django_filters.rest_framework import DjangoFilterBackend
  3.  
  4. class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
  5. '商品列表页'
  6.  
  7. #这里必须要定义一个默认的排序,否则会报错
  8. queryset = Goods.objects.all().order_by('id')
  9. # 分页
  10. pagination_class = GoodsPagination
  11. serializer_class = GoodsSerializer
  12. filter_backends = (DjangoFilterBackend,)
  13.  
  14. # 设置filter的类为我们自定义的类
  15. filter_class = GoodsFilter

二、drf的搜索和排序

添加搜索功能

搜索的字段可以使用正则表达式,更加的灵活

  1. class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
  2. '商品列表页'
  3.  
  4. #这里必须要定义一个默认的排序,否则会报错
  5. queryset = Goods.objects.all().order_by('id')
  6. # 分页
  7. pagination_class = GoodsPagination
  8. serializer_class = GoodsSerializer
  9. filter_backends = (DjangoFilterBackend,filters.SearchFilter)
  10.  
  11. # 设置filter的类为我们自定义的类
  12. filter_class = GoodsFilter
  13. #搜索,=name表示精确搜索,也可以使用各种正则表达式
  14. search_fields = ('=name','goods_brief')

添加排序功能

  1. class GoodsListViewSet(mixins.ListModelMixin,viewsets.GenericViewSet):
  2. '商品列表页'
  3.  
  4. #这里必须要定义一个默认的排序,否则会报错
  5. queryset = Goods.objects.all()
  6. # 分页
  7. pagination_class = GoodsPagination
  8. #序列化
  9. serializer_class = GoodsSerializer
  10. filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter)
  11.  
  12. # 设置filter的类为我们自定义的类
  13. #过滤
  14. filter_class = GoodsFilter
  15. #搜索,=name表示精确搜索,也可以使用各种正则表达式
  16. search_fields = ('=name','goods_brief')
  17. #排序
  18. ordering_fields = ('sold_num', 'add_time')

三、商品类别数据显示

1、商品类别数据接口

(1)商品分类有两个接口:

一种是全部分类:一级二级三级

一种是某一类的分类以及商品详细信息("CategoryViewSet"继承"mixins.RetrieveModelMixin"):

开始写商品分类的接口

(2)序列化

给分类添加三级分类的serializer

goods/serializers.py

  1. from rest_framework import serializers
  2. from .models import Goods,GoodsCategory
  3.  
  4. class CategorySerializer3(serializers.ModelSerializer):
  5. '''三级分类'''
  6. class Meta:
  7. model = GoodsCategory
  8. fields = "__all__"
  9.  
  10. class CategorySerializer2(serializers.ModelSerializer):
  11. '''
  12. 二级分类
  13. '''
  14. #在parent_category字段中定义的related_name="sub_cat"
  15. sub_cat = CategorySerializer3(many=True)
  16. class Meta:
  17. model = GoodsCategory
  18. fields = "__all__"
  19.  
  20. class CategorySerializer(serializers.ModelSerializer):
  21. """
  22. 商品一级类别序列化
  23. """
  24. sub_cat = CategorySerializer2(many=True) # “many=True”表示不止一个二级分类
  25. class Meta:
  26. model = GoodsCategory
  27. fields = "__all__"

(3)views.py

  1. class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
  2. '''
  3. list:
  4. 商品分类列表数据
  5. '''
  6.  
  7. queryset = GoodsCategory.objects.filter(category_type=1)
  8. serializer_class = CategorySerializer

说明:

  • 注释的内容,在后面生成drf文档的时候会显示出来,所有要写清楚
  • 要想获取某一个商品的详情的时候,继承 mixins.RetrieveModelMixin  就可以了(本来按照以前的做法,获取详情页需要我们配置url,以便获取某个商品id,但这些viewsets.GenericViewSet已经
  • 替我们完成了,不需要我们自己动手写代码)

(4)url配置

  1. # 配置Category的url
  2. router.register(r'categorys', CategoryViewSet, base_name="categorys")

2、vue展示商品分类数据

接口相关代码都放在src/api/api.js里面,调试接口的时候我们首先需要新建一个自己的host,然后替换要调试的host

(1)新建local_host

  1. let local_host = 'http://127.0.0.1:8000'

(2)替换商品类别默认的host

  1. //获取商品类别信息
  2. export const getCategory = params => {
  3. if('id' in params){
  4. return axios.get(`${local_host}/categorys/`+params.id+'/');
  5. }
  6. else {
  7. return axios.get(`${local_host}/categorys/`, params);
  8. }
  9. };

这个时候访问 http://127.0.0.1:8080/#/app/home/index

发现不显示商品分类了,是因为这涉及到了跨域问题,接下来就解决跨域的问题

(前端端口是8080,后端接口是8000,端口不同导致了跨域问题)

drf跨域问题

后端服务器解决跨域问题的方法

(1)安装模块

  1. pip install django-cors-headers

django-cors-headers 使用说明:https://github.com/ottoyiu/django-cors-headers

(2)添加到INSTALL_APPS中

  1. INSTALLED_APPS = (
  2. ...
  3.  
  4. 'coreschema',
  5.  
  6. ... )

(3)添加中间件

下面添加中间件的说明:

CorsMiddleware should be placed as high as possible, especially before any middleware that can generate responses such as Django's CommonMiddleware or Whitenoise's WhiteNoiseMiddleware. If it is not before, it will not be able to add the CORS headers to these responses.

Also if you are using CORS_REPLACE_HTTPS_REFERER it should be placed before Django's CsrfViewMiddleware (see more below).

意思就是 要放的尽可能靠前,必须在CsrfViewMiddleware之前。我们直接放在第一个位置就好了

  1. MIDDLEWARE = [
  2. 'corsheaders.middleware.CorsMiddleware',
  3. 'django.middleware.security.SecurityMiddleware',
  4. 'django.contrib.sessions.middleware.SessionMiddleware',
  5. 'django.middleware.common.CommonMiddleware',
  6. 'django.middleware.csrf.CsrfViewMiddleware',
  7. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  8. 'django.contrib.messages.middleware.MessageMiddleware',
  9. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  10. ]

(4)设置为True

  1. CORS_ORIGIN_ALLOW_ALL = True

现在再访问 http://127.0.0.1:8080/#/app/home/index   数据就可以填充进来了

在一级分类中设置为True

3、vue展示商品列表页数据

这里我们点击“tab”栏进行搜索和点击“热门关键词”进行搜索,左侧列表栏显示的数据是不一样的。点击“tab”栏,左侧显示的是一级和二级列表,点击“热门关键词”进行搜索,左侧显示的是三级的列表信息。那么是如何做到这点的呢??主要还是在前端,不同的方式搜索,虽然用的是同一个组件,但是所附加的参数不同,这样就区别开来了。

商品列表页会判断我们是serach还是getGoods

  1. getListData() {
  2. if(this.pageType=='search'){
  3. getGoods({
  4. search: this.searchWord, //搜索关键词
  5. }).then((response)=> {
  6. this.listData = response.data.results;
  7. this.proNum = response.data.count;
  8. }).catch(function (error) {
  9. console.log(error);
  10. });
  11. }else {
  12. getGoods({
  13. page: this.curPage, //当前页码
  14. top_category: this.top_category, //商品类型
  15. ordering: this.ordering, //排序类型
  16. pricemin: this.pricemin, //价格最低 默认为‘’ 即为不选价格区间
  17. pricemax: this.pricemax // 价格最高 默认为‘’
  18. }).then((response)=> {
  19.  
  20. this.listData = response.data.results;
  21. this.proNum = response.data.count;
  22. }).catch(function (error) {
  23. console.log(error);
  24. });
  25. }
  26.  
  27. },

说明:

(1)page分页

page_size数量与前端一致

页码参数与起前端一致"page"

  1. class GoodsPagination(PageNumberPagination):
  2. '''
  3. 商品列表自定义分页
  4. '''
  5. #默认每页显示的个数
  6. page_size = 12
  7. #可以动态改变每页显示的个数
  8. page_size_query_param = 'page_size'
  9. #页码参数
  10. page_query_param = 'page'
  11. #最多能显示多少页
  12. max_page_size = 100

(2)过滤

top_category是商品的一级分类,需要传入参数:一级分类的id

pricemin和pricemax与前端保持一致

获取一级分类下的所有商品

  1. # goods/filters.py
  2.  
  3. import django_filters
  4.  
  5. from .models import Goods
  6. from django.db.models import Q
  7.  
  8. class GoodsFilter(django_filters.rest_framework.FilterSet):
  9. '''
  10. 商品过滤的类
  11. '''
  12. #两个参数,name是要过滤的字段,lookup是执行的行为,‘小与等于本店价格’
  13. pricemin = django_filters.NumberFilter(name="shop_price", lookup_expr='gte')
  14. pricemax = django_filters.NumberFilter(name="shop_price", lookup_expr='lte')
  15. top_category = django_filters.NumberFilter(name="category", method='top_category_filter')
  16.   # 自定义我们想要的过滤逻辑
  17. def top_category_filter(self, queryset, name, value):
  18. # 不管当前点击的是一级分类二级分类还是三级分类,都能找到。
  19. return queryset.filter(Q(category_id=value) | Q(category__parent_category_id=value) | Q(
  20. category__parent_category__parent_category_id=value))
  21.  
  22. class Meta:
  23. model = Goods
  24. fields = ['pricemin', 'pricemax']

(3)排序

  GoodsListViewSet中ording与前端要一致

  1. #排序
  2. ordering_fields = ('sold_num', 'shop_price')

(4)替换为local_host

  1. //获取商品列表
  2. export const getGoods = params => { return axios.get(`${local_host}/goods/`, { params: params }) }

(5)搜索

  1. #搜索
  2. search_fields = ('name', 'goods_brief', 'goods_desc')

现在就可以从后台获取商品的数据了,主要功能

  • 分类过滤
  • 价格区间过滤
  • 显示商品数量
  • 分页
  • 搜索

Django REST framework+Vue 打造生鲜电商项目(笔记三)的更多相关文章

  1. Django REST framework+Vue 打造生鲜电商项目(笔记二)

    (转自https://www.cnblogs.com/derek1184405959/p/8768059.html)(有修改) 接下来开始引入django resfulframework,体现它的强大 ...

  2. Django REST framework+Vue 打造生鲜电商项目(笔记四)

    (PS:部分代码和图片来自博客:http://www.cnblogs.com/derek1184405959/p/8813641.html.有增删) 一.用户登录和手机注册 1.drf的token功能 ...

  3. Django REST framework+Vue 打造生鲜电商项目(笔记十)

    (from:https://www.cnblogs.com/derek1184405959/p/8877643.html  有修改) 十三.首页.商品数量.缓存和限速功能开发 首先把pycharm环境 ...

  4. Django REST framework+Vue 打造生鲜电商项目(笔记九)

    (from:http://www.cnblogs.com/derek1184405959/p/8859309.html) 十二.支付宝沙箱环境配置 12.1.创建应用 进入蚂蚁金服开放平台(https ...

  5. Django REST framework+Vue 打造生鲜电商项目(笔记十一)

    (form: http://www.cnblogs.com/derek1184405959/p/8886796.html 有修改) 十四.social_django 集成第三方登录 1.申请应用 进入 ...

  6. Django REST framework+Vue 打造生鲜电商项目(笔记八)

    (form:http://www.cnblogs.com/derek1184405959/p/8862569.html) 十一.pycharm 远程代码调试 第三方登录和支付,都需要有服务器才行(回调 ...

  7. Django REST framework+Vue 打造生鲜电商项目(笔记七)

    十.购物车.订单管理和支付功能 1.添加商品到购物车 (1)trade/serializer.py 这里的serializer不继承ModelSerializer,是因为自己写的Serializer更 ...

  8. Django REST framework+Vue 打造生鲜电商项目(笔记一)

    首先,这系列随笔是我个人在学习Bobby老师的Django实战项目中,记录的觉得对自己来说比较重要的知识点,不是完完整整的项目步骤过程....如果有小伙伴想找完整的教程,可以看看这个(https:// ...

  9. Django REST framework+Vue 打造生鲜电商项目(笔记六)

    (部分代码来自https://www.cnblogs.com/derek1184405959/p/8836205.html) 九.个人中心功能开发 1.drf的api文档自动生成 (1) url #d ...

随机推荐

  1. java多线程中篇(二) —— 线程的创建和Synchronized锁关键字

    学习之前,先了解线程状态图 说明:线程共包括以下5种状态. 1. 新建状态(New)         : 线程对象被创建后,就进入了新建状态.例如,Thread thread = new Thread ...

  2. SSM-CRUD

    一.项目介绍 前端技术:query+Bootstrap+ajax+json 后端技术:SSM(spring.springMVC.mybatis).JSR303校验 数据库:mysql 服务器:tomc ...

  3. Android持久化存储——(包含操作SQLite数据库)

    <第一行代码>读书手札 你可能会遇到的问题:解决File Explorer 中无显示问题 Android中,持久化存储,常见的一共有三种方法实现 (一.)利用文件存储 文件存储是Andro ...

  4. DjangoRestful 递归嵌套序列化器实现

    **** 由于博客园不支持markdown语法,所以推荐以下链接阅读: 原创 https://blog.csdn.net/weixin_42495873/article/details/8943354 ...

  5. vscode IIsExpress用法

    最近前端调试项目,都要安装IIS,使用IIS Express插件不需要另外在IIS架设站点,方便使用 1.安装IIS Express插件 2.ctrl+shfit+p 启动IIS Express 命令 ...

  6. 最全的ADB命令行大全(转)

    基本用法 命令语法 adb 命令的基本语法如下: adb [-d|-e|-s ] 如果只有一个设备/模拟器连接时,可以省略掉 [-d|-e|-s ] 这一部分,直接使用 adb . 为命令指定目标设备 ...

  7. VBA Do...While循环

    一个Do...while循环用于只要条件为真就重复一组语句.该条件可以在循环开始时或循环结束时检查. 语法 以下是VBA中的一个Do...While循环的语法. Do While condition ...

  8. 【转载】IIS网站如何同时解析带www和不带www的域名

    针对公网上线的网站系统,很多网站的域名会同时含有带www和不带www的域名解析记录,如果需要同时解析带www和不带www的域名信息,则需要在相应的域名解析平台(如阿里云域名解析平台.腾讯云域名解析平台 ...

  9. css 设置overflow:scroll 滚动条的样式

    /* 定义滚动条样式 */ ::-webkit-scrollbar { width: 6px; height: 6px; background-color: rgba(240, 240, 240, 1 ...

  10. JSONObject和URL以及HttpURLConnection的使用

    1 将java对象类转成json格式 首先引入依赖jar文件 注意依赖文件的版本号,高版本可能没有对应的类 2 我的实体类中包含内部类注意内部类要public才能被序列化成json格式 import ...