vue+django2.0.2-rest-framework 生鲜项目
一、首页相关-细节完善
1、首页轮播图
1)goods/serializers.py:新增轮播图序列化
class BannerSerializer(serializers.ModelSerializer): ''' 轮播图 ''' class Meta: model = Banner fields = "__all__"
2)goods/views.py:新增首页轮播图view
class BannerViewset(mixins.ListModelMixin, viewsets.GenericViewSet): """ 首页轮播图 """ queryset = Banner.objects.all().order_by("index") serializer_class = BannerSerializer
3)url配置:
# 配置首页轮播图的url router.register(r'banners', BannerViewset, base_name="banners")
2、首页-新品模块
使用的是url是goods(商品)下的url路由,所以只需要在filter(过滤器)中加上字段:is_new ,就可以了
class GoodsFilter(django_filters.rest_framework.FilterSet): ''' 自定义过滤器,实现区间过滤 商品过滤的类 ''' …… class Meta: model = Goods fields = ['pricemin', 'pricemax','top_category','is_hot','is_new'] # 新增‘is_new’字段
3、首页商品分类显示功能
首先是大类,然后里面有
- 商品商标(多个)
- 大类下的二级类
- 广告商品
- 所有商品
1)goods/models.py中新增表:
class IndexAd(models.Model): """ 首页类别标签右边展示的七个商品广告 """ category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, related_name='category',verbose_name="商品类目") goods =models.ForeignKey(Goods, on_delete=models.CASCADE, related_name='goods') class Meta: verbose_name = '首页广告' verbose_name_plural = verbose_name def __str__(self): return self.goods.name
2)goods/xadmin.py:注册IndexAd
class IndexAdAdmin(object): list_display = ["category", "goods"] xadmin.site.register(IndexAd, IndexAdAdmin)
3)goods/serializers.py:
class BrandSerializer(serializers.ModelSerializer): ''' 大类下面的宣传商标 ''' class Meta: model = GoodsCategoryBrand fields = "__all__" class IndexCategorySerializer(serializers.ModelSerializer): #某个大类的商标,可以有多个商标,一对多的关系 brands = BrandSerializer(many=True) # good有一个外键category,但这个外键指向的是三级类,直接反向通过外键category(三级类),取某个大类下面的商品是取不出来的 goods = serializers.SerializerMethodField() # 在parent_category字段中定义的related_name="sub_cat" # 取二级商品分类 sub_cat = CategorySerializer2(many=True) # 广告商品 ad_goods = serializers.SerializerMethodField() def get_ad_goods(self, obj): goods_json = {} ad_goods = IndexAd.objects.filter(category_id=obj.id, ) if ad_goods: #取到这个商品Queryset[0] good_ins = ad_goods[0].goods #在serializer里面调用serializer的话,就要添加一个参数context(上下文request),嵌套serializer必须加 # serializer返回的时候一定要加 “.data” ,这样才是json数据 goods_json = GoodsSerializer(good_ins, many=False, context={'request': self.context['request']}).data return goods_json #自定义获取方法 def get_goods(self, obj): # 将这个商品相关父类子类等都可以进行匹配 all_goods = Goods.objects.filter(Q(category_id=obj.id) | Q(category__parent_category_id=obj.id) | Q( category__parent_category__parent_category_id=obj.id)) goods_serializer = GoodsSerializer(all_goods, many=True, context={'request': self.context['request']}) return goods_serializer.data class Meta: model = GoodsCategory fields = "__all__"
4)goods/views.py:
class IndexCategoryViewset(mixins.ListModelMixin, viewsets.GenericViewSet): """ 首页商品分类数据 """ # 获取is_tab=True(导航栏)里面的分类下的商品数据 queryset = GoodsCategory.objects.filter(is_tab=True, name__in=["生鲜食品", "酒水饮料"]) serializer_class = IndexCategorySerializer
5)urls.py配置:
# 首页系列商品展示url router.register(r'indexgoods', IndexCategoryViewset, base_name="indexgoods")
4、商品点击数跟收藏数
1)点击数
GoodsListViewSet其中继承了mixins.RetrieveModelMixin(获取商品详情),当用户访问某个商品详情时,让商品点击数加1
重写retrieve()方法
#商品点击数 + 1 def retrieve(self, request, *args, **kwargs): instance = self.get_object() instance.click_num += 1 instance.save() serializer = self.get_serializer(instance) return Response(serializer.data)
完整代码:
goods/views.py/GoodsListViewSet:
class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin,viewsets.GenericViewSet): ''' list: 商品列表,分页,搜索,过滤,排序 retrieve: 获取商品详情 ''' # authentication_classes = (TokenAuthentication,) #这里必须要定义一个默认的排序,否则会报错 queryset = Goods.objects.all().order_by('id') # 分页 pagination_class = GoodsPagination #序列化 serializer_class = GoodsSerializer filter_backends = (DjangoFilterBackend,filters.SearchFilter,filters.OrderingFilter) # 设置filter的类为我们自定义的类 #过滤 filter_class = GoodsFilter #搜索 search_fields = ('name', 'goods_brief', 'goods_desc') #排序 ordering_fields = ('sold_num', 'shop_price') #商品点击数 + 1 def retrieve(self, request, *args, **kwargs): instance = self.get_object() instance.click_num += 1 instance.save() serializer = self.get_serializer(instance) return Response(serializer.data)