【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能

专题:Vue+Django REST framework前后端分离生鲜电商

Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。
Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ;
Django版本:2.2、djangorestframework:3.9.2。
前端Vue模板可以直接联系我拿。

更多内容请点击 我的博客 查看,欢迎来访。

首页、商品相关功能

接下来把Django运行到本地,Vue也运行到本地

首先修改Django虚拟环境

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第1张图片

修改运行环境

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第2张图片

然后以Debug运行起来,浏览器访问 http://127.0.0.1:8000/ 看是否显示API就可以了

将Vue中 src/api/api.js 修改到本地

let local_host = 'http://localhost:8000';
//let local_host = 'http://xx.ip.ip.xx:8000';

启用Vue本地服务器,访问 http://127.0.0.1:8080/ 看能否正常加载Vue项目即可。

重新打包Vue项目> cnpm run build,将 dist 目录下的 index.entry.js 文件复制到Django项目 static 目录下。

由于本地启动到 http://127.0.0.1:8000/ 上,代理Vue运行后,调用 http://localhost:8000 就会出现跨域问题,解决办法:1是修改local_host,2是修改 DjangoOnlineFreshSupermarket/settings.py 中的CORS_ORIGIN_WHITELIST,增加'localhost:8000',

# 跨域CORS设置
# CORS_ORIGIN_ALLOW_ALL = False  # 默认为False,如果为True则允许所有连接
CORS_ORIGIN_WHITELIST = (  # 配置允许访问的白名单
    'localhost:8080',
    'localhost:8000',
    '127.0.0.1:8080',
    '127.0.0.1:8000',
)

之后访问就正常了。

分析:首页有轮播图、新品,商品列表

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第3张图片

首页Index中有Banner和NewP、SeriesList为一些列首页显示的商品

也就是需要3个接口:轮播图、新品、首页商品列表

首页轮播图

BannerSerializer创建轮播图序列化类

在 apps/goods/serializers.py 中添加 BannerSerializer

from .models import Goods, GoodsCategory, GoodsImage, Banner

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

BannerViewSet轮播图显示

在 apps/goods/views.py 添加 BannerViewSet

from .models import Goods, GoodsCategory, Banner
from .serializers import GoodsSerializer, CategorySerializer, ParentCategorySerializer, BannerSerializer

class BannerViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    list:
        获取轮播图列表
    """
    queryset = Banner.objects.all()
    serializer_class = BannerSerializer

添加轮播图路由

from goods.views import GoodsListView, GoodsListViewSet, CategoryViewSet, ParentCategoryViewSet, BannerViewSet

# 注册轮播图url
router.register(r'banners', BannerViewSet, base_name='banners')  # 首页轮播图

接下来访问 http://127.0.0.1:8000/banners/ 接口

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第4张图片

什么都没显示,接下来访问后台添加一些轮播图 http://127.0.0.1:8000/admin/goods/banner/add/

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第5张图片

百度随意找一些添加进去,然后刷新 http://127.0.0.1:8000/banners/ 就可以看到API中的列表了

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第6张图片

Vue轮播图接口联调

刷新Vue的 http://127.0.0.1:8080/#/app/home/index 首页

[外链图片转存失败(img-j5E59D3p-1565761934048)(https://blog.starmeow.cn/media/blog/images/2019/08/BLOG_20190814_134716_21.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190814_134716_21.png”)]

进入首页后,引用了 src/views/index/banners.vue 这个组件,当这个组件创建时

        created() {
            this.getBanner();
        }

调用getBanner()方法

            getBanner() {
                bannerGoods()
                    .then((response) => {
                        //console.log(response)
                        // 跳转到首页页response.body面
                        this.banners = response.data
                    })
                    .catch(function (error) {
                        console.log(error);
                    });
            }

这儿会调用bannerGoods(),也就是 src/api/api.js 中的接口

//获取轮播图
export const bannerGoods = params => {
    return axios.get(`${local_host}/banners/`)
};

拿到数据后赋值给banners

        <swiper :options="swiperOption">
            <swiper-slide v-for="item in banners" :key="item.goods">
                <router-link :to="'/app/home/productDetail/'+item.goods" target=_blank><img :src="item.image" alt=""/>
                router-link>
            swiper-slide>
            <div class="swiper-pagination" slot="pagination">div>
        swiper>

循环显示所有数据。点击图片就可以跳转到对应的商品。

首页新品展示

对于新品,可以直接使用商品列表的接口。因为在Goods的models中有一个字段是is_new = models.BooleanField(default=False, verbose_name='是否新品', help_text='是否新品'),如果是要显示新品,无非是直接过滤商品中is_new是非为True即可。

GoodsFilter过滤器增加新品过滤

在 apps/goods/views.py 中的GoodsListViewSet,过滤器是使用的filterset_class = GoodsFilter,可以直接添加is_new这个字段

class GoodsFilter(filters.FilterSet):
    """
    商品的过滤类
    """
    name = filters.CharFilter(field_name='name', lookup_expr='contains', help_text='分类名模糊匹配')  # 包含关系,模糊匹配
    goods_desc = filters.CharFilter(field_name='name', lookup_expr='contains', help_text='商品描述模糊匹配')
    min_price = filters.NumberFilter(field_name="shop_price", lookup_expr='gte', help_text='最低价格')  # 自定义字段
    max_price = filters.NumberFilter(field_name="shop_price", lookup_expr='lte', help_text='最高价格')
    top_category = filters.NumberFilter(method='top_category_filter', field_name='category_id', lookup_expr='=', help_text='自定义过滤某个一级分类')  # 自定义过滤,过滤某个一级分类

    def top_category_filter(self, queryset, field_name, value):
        """
        自定义过滤内容
        这儿是传递一个分类的id,在已有商品查询集基础上获取分类id,一级一级往上找,直到将三级类别找完
        :param queryset:
        :param field_name:
        :param value: 需要过滤的值
        :return:
        """
        queryset = queryset.filter(Q(category_id=value) | Q(category__parent_category_id=value) | Q(category__parent_category__parent_category_id=value))
        return queryset

    class Meta:
        model = Goods
        fields = ['name', 'goods_desc', 'min_price', 'max_price', 'is_hot', 'is_new']

然后刷新 http://127.0.0.1:8000/goods/ 点击过滤器就可以就行该字段过滤了

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第7张图片

没有内容因为数据库中没有设置新品

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第8张图片

随意在数据库中把一些商品标记为新品即可

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第9张图片

刷新API页面,就能正常显示了

【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能_第10张图片

Vue新品接口联调

在Vue中,新品放在 src/views/index/new.vue 组件中,index调用这个组件时,会调用getOpro()方法

            getOpro() {
                getGoods({
                    "is_new": "true"
                })
                    .then((response) => {
                        //跳转到首页页response.body面
                        this.newopro = response.data.results
                    })
                    .catch(function (error) {
                        console.log(error);
                    });
            }

然后调用 getGoods,实际上也是调用商品列表

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

只是传递了"is_new": "true"这个参数,由于返回的结果response.data商品列表进行了分页,需要使用response.data.results才能正确取到值

将这些商品显示出来

<li class="prolist-cent clearfix have_num" v-for="item in newopro">
    <div class="prolist-l fl">
        <router-link :to="'/app/home/productDetail/'+item.id" target=_blank>
            <a :title="item.name" class="imgBox">
                <img :src="item.goods_front_image" style="height: 158px;width: 158px;" class="zom"
                     :alt="item.name">
            a>
        router-link>
    div>
    <div class="prolist-r fl">
        <h3 class="ft14 c333 bold">
            <router-link :to="'/app/home/productDetail/'+item.id" :title="item.name" target=_blank>
                {{item.name}}
            router-link>
        h3>
        <p><em class="c333">em>{{item.goods_brief}}p>
        <div>

            <span class="p-price"><em class="fastbuy_price">¥{{item.shop_price}}元em><del>原价:¥{{item.market_price}}元del>span>
            <router-link :to="'/app/home/productDetail/'+item.id" target=_blank>
                <a class="p-buy fr ibg">立即抢购a>
            router-link>
            <span class="p-time fr">销量:{{item.sold_num}}件span>
        div>
    div>
li>

[外链图片转存失败(img-kwo2Jt5l-1565761934049)(https://blog.starmeow.cn/media/blog/images/2019/08/BLOG_20190814_134519_12.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 “博客图集BLOG_20190814_134519_12.png”)]

点击商品的链接,即可跳转到商品详情页。

你可能感兴趣的:(Web开发)