goods/views.py
class CategoryViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
"""
RetrieveModelMixin 参数可以使得前端输入http://127.0.0.1:8000/categorys/1/而显示id为1的商品,相当于restful接口的GET操作 GET /zoos/ID:获取某个指定动物园的信息
list:
商品分类列表
"""
queryset = GoodsCategory.objects.all()
serializer_class = CategorySerializer
goods/serializers.py
from goods.models import Goods,GoodsCategory
class CategorySerializer3(serializers.ModelSerializer): #此处为三级类目:鱼,虾等
class Meta:
model = GoodsCategory
fields = "__all__"
class CategorySerializer2(serializers.ModelSerializer): # 则这里是二级类目:海鲜水产
sub_cat = CategorySerializer3(many=True)
class Meta:
model = GoodsCategory
fields = "__all__"
class CategorySerializer(serializers.ModelSerializer): # 若此处为一级类目:生鲜食品
# 因为商品类别中有三级,GoodsCategory类以自身作为外键,三级是二级的外键,二级是一级的外键
# 可以用如下方式在前段显示外键
sub_cat = CategorySerializer2(many=True) # 注:sub_cat与model中GoodsCategory中的related_name一样
class Meta:
model = GoodsCategory
fields = "__all__"
主url中配置
# 配置category的url
router.register(r'categorys', CategoryViewSet, base_name='categorys')
这样在前端就只显示1的商品
在前端页面的导航栏中显示信息,需要先把host主机名配置
因为django启动的是8000端口,而cnpm启动的是8080端口,涉及到跨域问题,可以前端解决,这里用django后端方式解决。安装https://github.com/ottoyiu/django-cors-headers 这个包,然后再settings中配置:INSTALLED_APPS中添加‘corsheaders’;MIDDLEWARE中添加‘corsheaders.middleware.CorsMiddleware’;再添加CORS_ORIGIN_ALLOW_ALL = True。这样前端就显示出数据。
以上在vue的大致实现流程如下
然后使用vue的for循环取出数据
接下来在xadmin中添加数据显示到导航栏(因为在vue中有item.is_tab为true才会显示,所以在xadmin中要把是否需要导航的√打上)
这样在前端就显示了
问题:点击从下面的1,2,3中的生鲜食品,牛奶等词,前端页面是如何显示的呢?
当点击1选项时,进入head.vue的search中,点击2,3会进入list,是通过 + item.id 来进行的
然后vue再到router的index.js中,不管di找到点击的是1还是2,3,他们的组件都是list
vue再接着就进入list.vue,这个list组件刚初始化的时候会先调用createdhans方法,调用里面的getAllData方法
再接着调用getAllData方法
再调用list.vue的getMenu方法。根据id是否为空,进入不同的逻辑,再调用getCategory方法
在接着跳转到api.js,这样就能向django发送请求了。
当vue收到django的消息后,进入then逻辑
然后传递下下面的list的组件中
6-5 vue如何获取goods
注:将django的goods/views.py的p改为page,与上图的page保持一致(这样vue点击页面数字才能切换)
接下来由于vue中写了top_category,所以drf中过滤器中也要写top_category(暂时不知道vue中的top_cartegory怎么作用到后端的,如果不写,前段商品页面点击类别无法跳转出对应的商品
在后端中这么写
class GoodsFilter(django_filters.rest_framework.FilterSet):
pricemin = django_filters.NumberFilter(name='shop_price',lookup_expr='gte')
pricemax = django_filters.NumberFilter(name='shop_price',lookup_expr='lte')
name = django_filters.CharFilter(name='name',lookup_expr='icontains')
top_category = django_filters.NumberFilter(method='top_category_filter')
def top_category_filter(self,queryset,name,value):
# 过滤出商品的父类的id等于value的商品(value就是网页上过滤器上提交的过滤的值)
return queryset.filter(Q(category_id=value)|Q(category__parent_category_id=value)|Q(category__parent_category__parent_category_id=value))
#category_id:商品的父类别(3级类目),category__parent_category_id:商品的父类别的父类别(2级类目)
# 参见 https://blog.csdn.net/qq_34964399/article/details/79515440/其实就是正向查找
class Meta:
model = Goods
fields = ['pricemin','pricemax','name']
这样你在drf的前段页面就能过滤出需要的内容了,这个就是搜索出商品的类别(包括一级类别,二级类别,三级类别)id为1的商品,共有14件