本文共 7236 字,大约阅读时间需要 24 分钟。
1.轮播图
轮播图没东西 因为之前涉及了model 所以直接使用ListModelMixin就好了 Serializer也是获得所有即可。
代码:
# models.pyclass GoodsImage(models.Model): """ 商品轮播图 """ goods = models.ForeignKey(Goods, verbose_name=u'商品', related_name = 'images', on_delete=models.CASCADE) image = models.ImageField(upload_to='', verbose_name=u'图片', null=True, blank=True) index = models.IntegerField(default=0, verbose_name=u'轮播顺序') add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加时间') class Meta: verbose_name = u'商品图片' verbose_name_plural = verbose_name def __str__(self): return self.goods.name# views.pyfrom .models import Bannerfrom .serializers import BannerSerializerclass BannerViewset(mixins.ListModelMixin, viewsets.GenericViewSet): """ 获取轮播图列表 """ queryset = Banner.objects.all().order_by("index") serializer_class = BannerSerializer# serializers.pyfrom goods.models import Bannerclass BannerSerializer(serializers.ModelSerializer): class Meta: model = Banner fields = "__all__"# urls.pyfrom goods.views import BannerViewsetrouter.register('banners', BannerViewset, base_name='banners')
这样轮播图就完成了
2.新品功能开发;
因为新品是goods(model)中的一个字段名 所以只需要将过滤条件增加一个就可以了
# 之前写的那个fitlers.py 在fields中增加一个‘is_new’元素即可# encoding:utf-8import django_filtersfrom django.db.models import Qfrom .models import Goodsclass GoodsFilter(django_filters.rest_framework.FilterSet): """ 商品的过滤类 """ pricemin = django_filters.NumberFilter(field_name='shop_price', lookup_expr='gte', help_text="最低价格") pricemax = django_filters.NumberFilter(field_name='shop_price', lookup_expr='lte') # 获取相应类别下的所有商品 top_category = django_filters.NumberFilter(method='top_category_filter') # 这是全部匹配 name = django_filters.CharFilter(field_name='name')# 这是部分匹配 不分大小写# name = django_filters.CharFilter(field_name='name', lookup_expr='icontains') def top_category_filter(self, queryset, name, value): return queryset.filter(Q(category_id = value) | Q(category__parent_category_id = value) | Q(category__parent_category__parent_category_id = value)) class Meta: model = Goods# ------------------------------------------------------> 这里 fields = ['pricemin','pricemax', 'name', 'is_hot', 'is_new']
3. 商品分类显示
主页的这部分
这里面涉及了很多内容 多层级的1对多的关系
先做商品类型的展示,就是图片左下角的那些
class IndexCategorySerializer(serializers.ModelSerializer): class Meta: model = GoodsCategory fields = "__all__"
首先先做品牌展示 利用商品类别来方向选择对应类别的品牌
在model中我们添加related_name参数,这样方便做反向选择
# models.py/class GoodsCategoryBrand# Django2.0以上需要增加on_delete参数 针对外键 category = models.ForeignKey(GoodsCategory, related_name="brands", null=True, blank=True, verbose_name=u'商品类目', on_delete=models.CASCADE)
这样在goods_category中就可以反向拿到brand(品牌)了
然后我们在写一个brand的Serializer 然后嵌套到IndexSerializer中
这里有一个要明确 indexSerializer是包含上面截的整张图的所有信息。所以 相关的Serializer都会嵌套进去 统一返回给前端
# Serializers.pyclass BannerSerializer(serializers.ModelSerializer): class Meta: model = Banner fields = "__all__"class IndexCategorySerializer(serializers.ModelSerializer): brands = BrandSerializer(many=True) class Meta: model = GoodsCategory fields = "__all__"
为什么不能直接用goods的Serializer。
goods中确实有一个外键指向我们的category。为什么不能反向取。
>因为商品选择哪个类别的时候,往往选择的是最小的类别。(第三类)
而不是直接从属于第一类。获取商品:
外键指向的第三类。而我们要拿到第一类别的数据。直接使用goods的Serializer取不出来。
自定义商品(取相应类别的商品,使用自定义函数Serializer字段)
class IndexCategorySerializer(serializers.ModelSerializer): brands = BrandSerializer(many=True) goods = serializers.SerializerMethodField() 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) return goods_serializer.data
获取二类商品类别,利用之前做过的那个GategorySerializer2
class IndexCategorySerializer(serializers.ModelSerializer): brands = BrandSerializer(many=True) goods = serializers.SerializerMethodField() sub_cat = CategorySerializer2(many=True)# 这是之前做的class CategorySerializer2(serializers.ModelSerializer): sub_cat = CategorySerializer3(many=True) class Meta: model = GoodsCategory fields = "__all__"
最后搞右边的那7张图片
先去建model
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
然后在IndexCategorySerializer中增加这些广告
from goods.models import IndexAdclass IndexCategorySerializer(serializers.ModelSerializer): brands = BrandSerializer(many=True) goods = serializers.SerializerMethodField() 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: goods_ins = ad_goods[0].goods goods_json = GoodsSerializer(goods_ins, many=False).data return goods_json
这时候输出到前端的img路径是不包含url地址的。 因为我们在Serializer中嵌套了serializer 并且还自定义了序列化方法。 这样的形式默认是不会加上url的 所以我们需要在嵌套的Serializer中加上context参数
def get_ad_goods(self, obj): goods_json = {} ad_goods = IndexAd.objects.filter(category_id = obj.id) if ad_goods: goods_ins = ad_goods[0].goods# --------------------------------------------------------------> 这里 goods_json = GoodsSerializer(goods_ins, many=False, context={'request': self.context['request']}).data return goods_json
这样输出到前端的图片路径就是包含URL域名的了。 帖完整的Serializer代码
from goods.models import Goods, GoodsCategory, GoodsImage, Banner, GoodsCategoryBrand, IndexAdfrom django.db.models import Qclass IndexCategorySerializer(serializers.ModelSerializer): brands = BrandSerializer(many=True) goods = serializers.SerializerMethodField() 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: goods_ins = ad_goods[0].goods goods_json = GoodsSerializer(goods_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__"
然后我们来写view
class IndexCategoryViewset(mixins.ListModelMixin, viewsets.GenericViewSet): """ 首页商品分类数据 """# 限定了是否是用于导航 并且限定了两类商品(正式环境是不限定商品类型) queryset = GoodsCategory.objects.filter(is_tab=True, name__in=["生鲜食品","酒水饮料"]) serializer_class = IndexCategorySerializer
urls.py:
#主页商品系列数据router.register('indexgoods', IndexCategoryViewset, base_name='indexgoods')
转载地址:http://gsepi.baihongyu.com/