我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

一、首頁功能完善

首頁待完善的功能包括輪播圖、新品嚐鮮、系列商品等。

1.輪播圖實現

輪播圖包括3張圖片,鏈接對應3個商品,先在apps/goods/serializers.py中定義序列化如下:

<code>class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = '__all__'/<code>

再在views.py中定義視圖如下:

<code>class BannerViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    '''
    list:
        輪播圖列表
    '''
    queryset = Banner.objects.filter(is_delete=False).order_by('index')
    serializer_class = BannerSerializer/<code>

再在urls.py中定義路由如下:

<code># 配置輪播圖路由
router.register(r'banners', BannerViewSet, basename='banners')/<code>

測試如下:

我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

可以看到,開始沒有輪播圖數據,經過在管理後臺添加數據後,即同步數據。

前端src/views/index/banners.vue如下:

<code>
    
     
    
    

methods:{ getBanner(){ bannerGoods() .then((response)=> { console.log(response) //跳轉到首頁頁response.body面 this.banners = response.data }) .catch(function (error) { console.log(error); }); } }, created(){ this.getBanner(); }/<code>

在初始化時調用getBanner()方法,在調用bannerGoods接口請求數據,請求到的數據再通過for循環展示出來。

api.js修改如下:

<code>//獲取輪播圖
export const bannerGoods = params => { return axios.get(`${local_host}/banners/`) }/<code>

此時再進行測試如下:

我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

顯然,請求的圖片數據已從本地加載,並且點擊輪播圖片會調皮轉到相應的商品鏈接。

2.新品功能開發

在定義商品模型時定義了is_new字段表示是否是新品,再實現新品功能時需要用到該字段,直接使用Goods接口並在filters.py過濾器中定義即可,如下:

<code>class GoodsFilter(django_filters.rest_framework.FilterSet):
    '''商品過濾類'''
    name = django_filters.CharFilter(field_name="name", lookup_expr='contains')
    pricemin = django_filters.NumberFilter(field_name="market_price", lookup_expr='gte')
    pricemax = django_filters.NumberFilter(field_name="market_price", lookup_expr='lte')
    top_category = django_filters.NumberFilter(method='top_category_filter')

    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 = ['name', 'pricemin', 'pricemax', 'is_hot', 'is_new']/<code>

演示如下:

我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

顯然,在手動添加新品之後,新品數據即同步,請求的參數中包含is_new=true。

前端src/views/index/news.vue如下:

可以看到,在初始化時,調用getOpro()方法,在調用getGoods接口時傳入參數is_new,來獲取新品,與之前獲取商品調用的接口相同,獲取到數據後通過for循環顯示出來。

訪問示意如下:

我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

3.商品系列分類展示功能

商品系列分類包括左側的導航欄和右側的商品列表,大類對應多個品牌、大類對應多個小類、大類對應多個商品,即包含3個一對多關係,在定義序列化時需要嵌套定義

為了實現嵌套,在定義GoodsCategoryBrand模型時需要指定related_name屬性,如下:

<code>class GoodsCategoryBrand(models.Model):
    '''品牌名'''
    category = models.ForeignKey(GoodsCategory, verbose_name='商品類目', related_name='brands', null=True, on_delete=models.SET_NULL)
    name = models.CharField(default='', max_length=30, verbose_name='品牌名', help_text='品牌名')
    desc = models.TextField(default='', max_length=200, verbose_name='品牌描述', help_text='品牌描述')
    image = models.ImageField(max_length=200, upload_to='brands/')
    add_time = models.DateTimeField(default=datetime.now, verbose_name=u'添加時間')
    is_delete = models.BooleanField(default=False, verbose_name='是否刪除')

    class Meta:
        verbose_name = '品牌'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

class IndexAd(models.Model):
    category = models.ForeignKey(GoodsCategory, verbose_name='商品類目', related_name='category', null=True, on_delete=models.SET_NULL)
    goods = models.ForeignKey(Goods, verbose_name='商品', related_name='goods', null=True, on_delete=models.SET_NULL)

    class Meta:
        verbose_name = '首頁商品類別廣告'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.goods.name/<code>

完成後需要進行數據映射。

為了在創建brand時只顯示一級類別,在adminx.py中定義GoodsBrandAdmin類時重寫了get_context()方法,其中獲取到category字段只取category_type為1的數據,如下:

<code>定義序列化如下:

class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = '__all__'


class BrandSerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategoryBrand
        fields = '__all__'


class IndexCategorySerializer(serializers.ModelSerializer):
    brands = BrandSerializer(many=True)
    goods = serializers.SerializerMethodField()
    sub_cat = SecCategorySerializer(many=True)
    ad_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

    def get_ad_goods(self, obj):
        goods_json = {}
        ad_goods = IndexAd.objects.filter(category_id=obj.id)
        if ad_goods:
            good_instance = ad_goods[0].goods
            goods_json = GoodsSerializer(good_instance, many=False).data
        return goods_json

    class Meta:
        model = GoodsCategory
        fields = '__all__'class GoodsBrandAdmin(object):
    list_display = ["category", "image", "name", "desc"]

    def get_context(self):
        context = super(GoodsBrandAdmin, self).get_context()
        if 'form' in context:
            context['form'].fields['category'].queryset = GoodsCategory.objects.filter(category_type=1)
        return context/<code>

定義序列化如下:

<code>class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = '__all__'


class BrandSerializer(serializers.ModelSerializer):
    class Meta:
        model = GoodsCategoryBrand
        fields = '__all__'


class IndexCategorySerializer(serializers.ModelSerializer):
    brands = BrandSerializer(many=True)
    goods = serializers.SerializerMethodField()
    sub_cat = SecCategorySerializer(many=True)
    ad_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

    def get_ad_goods(self, obj):
        goods_json = {}
        ad_goods = IndexAd.objects.filter(category_id=obj.id)
        if ad_goods:
            good_instance = ad_goods[0].goods
            goods_json = GoodsSerializer(good_instance, many=False).data
        return goods_json

    class Meta:
        model = GoodsCategory
        fields = '__all__'/<code>

可以看到,定義了多個一對多的關係和一個一對一的關係,視圖如下:

<code>定義路由如下:

# 配置首頁商品系列路由
router.register(r'indexgoods', IndexCategoryViewSet, basename='indexgoods')class IndexCategoryViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    '''
    list:
        商品分類數據
    '''

    queryset = GoodsCategory.objects.filter(is_delete=False, is_tab=True, name__in=['生鮮食品', '酒水飲料'])
    serializer_class = IndexCategorySerializer


/<code> 

定義路由如下:

<code># 配置首頁商品系列路由
router.register(r'indexgoods', IndexCategoryViewSet, basename='indexgoods')/<code>

進行測試:

我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

可以看到,再添加數據brands和ad_goods之前這兩類數據為空,添加之後數據同步。

但是同時也可以看到,在商品的image屬性的值即圖片鏈接中未自動添加域名,這是因為進行嵌套序列化默認不會添加域名,需要給字段設置

context屬性,配置如下:

<code>class IndexCategorySerializer(serializers.ModelSerializer):
    brands = BrandSerializer(many=True)
    goods = serializers.SerializerMethodField()
    sub_cat = SecCategorySerializer(many=True)
    ad_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, context={'request': self.context['request']})
        return goods_serializer.data

    def get_ad_goods(self, obj):
        goods_json = {}
        ad_goods = IndexAd.objects.filter(category_id=obj.id)
        if ad_goods:
            good_instance = ad_goods[0].goods
            goods_json = GoodsSerializer(good_instance, many=False, context={'request': self.context['request']}).data
        return goods_json

    class Meta:
        model = GoodsCategory
        fields = '__all__'/<code>

此時再查看如下:

我給我大姨用Django+Vue開發生鮮電商平臺!在鄉下也能網購了

顯然,已經將域名顯示出來。

前端src/views/index/series-list.vue如下:


分享到:


相關文章: