十日Python项目——第五日(商品数据)

news2024/11/15 19:53:07

#前言:

在最近十天我会用Python做一个购物类项目,会用到Django+Mysql+Redis+Vue等。

今天是第五天,主要负责撰写响应具体的商品数据。若是有不懂大家可以先阅读我的前四篇博客以能够顺承。

若是大家基础有不懂的,小编前面已经关于Django博客都更新完了,大家可以自行查看。若是有需要更改的地方欢迎大家指正,同时也欢迎大家关注点赞收藏等待后续,小编会尽力更新优质博客。

在此我会直接继承上一篇博客继续往下写。

十、商品数据:

1、建立模型类: 

关于商品数据,我们在统计时候我们可以按照一个大类再嵌套一个小类再嵌套具体的商品。

而具体的我们按照两大类:

SPU 和 SKU

SPU:标准化产品单位 , SPU 是商品信息聚合的最小单位,比如:Iphone 15就是一个 SPU;体现一件商品的基本特征;
    在数据库中 ,SPU 一般包含了商品的通用属性 ,品牌 , 型号 , 主要功能等。

SKU:库存量单位,SKU是库存管理和销售的最小单位 , 在同一个 SPU 下可能会有多个 SKU;SKU是包含商品的具体属性:颜色,大小,配置,产地。

1.1、首页模型类:

在首页中我们要响应关于商品的一些广告和分类内容。

from django.db import models
from utils.model import BaseModel

class ContentCategory(BaseModel):
    """广告内容类别"""
    name = models.CharField(max_length=50, verbose_name='名称')
    key = models.CharField(max_length=50, verbose_name='类别键名')

    class Meta:
        db_table = 'tb_content_category'
        verbose_name = '广告内容类别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class Content(BaseModel):
    """广告内容"""
    category = models.ForeignKey(ContentCategory, on_delete=models.PROTECT, verbose_name='类别')
    title = models.CharField(max_length=100, verbose_name='标题')
    url = models.CharField(max_length=300, verbose_name='内容链接')
    image = models.ImageField(null=True, blank=True, verbose_name='图片')
    text = models.TextField(null=True, blank=True, verbose_name='内容')
    sequence = models.IntegerField(verbose_name='排序')
    status = models.BooleanField(default=True, verbose_name='是否展示')

    class Meta:
        db_table = 'tb_content'
        verbose_name = '广告内容'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.category.name + ': ' + self.title

1.2、商品模型类:

关于商品的一些模型类我们首先创建一个应用goods,在goods的models文件下要建立多个模型类:

from django.db import models
from utils.model import BaseModel

class GoodsCategory(BaseModel):
    """商品类别"""
    name = models.CharField(max_length=10, verbose_name='名称')
    parent = models.ForeignKey('self', related_name='subs', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父类别')

    class Meta:
        db_table = 'tb_goods_category'
        verbose_name = '商品类别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class GoodsChannelGroup(BaseModel):
    """商品频道组"""
    name = models.CharField(max_length=20, verbose_name='频道组名')

    class Meta:
        db_table = 'tb_channel_group'
        verbose_name = '商品频道组'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class GoodsChannel(BaseModel):
    """
    商品频道
    对每一类商品进行分组 , 方便构造项目的导航栏
    将上面两个模型合在一起
    """
    group = models.ForeignKey(GoodsChannelGroup, verbose_name='频道组名', on_delete=models.CASCADE)
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='顶级商品类别')
    url = models.CharField(max_length=50, verbose_name='频道页面链接')
    sequence = models.IntegerField(verbose_name='组内顺序')

    class Meta:
        db_table = 'tb_goods_channel'
        verbose_name = '商品频道'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.category.name


class Brand(BaseModel):
    """品牌"""
    name = models.CharField(max_length=20, verbose_name='名称')
    logo = models.ImageField(verbose_name='Logo图片')
    first_letter = models.CharField(max_length=1, verbose_name='品牌首字母')

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

    def __str__(self):
        return self.name


class SPU(BaseModel):
    """商品SPU
    连接了第一个模型类
    """
    name = models.CharField(max_length=50, verbose_name='名称')
    brand = models.ForeignKey(Brand, on_delete=models.PROTECT, verbose_name='品牌')
    category1 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat1_spu', verbose_name='一级类别')
    category2 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat2_spu', verbose_name='二级类别')
    category3 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat3_spu', verbose_name='三级类别')
    sales = models.IntegerField(default=0, verbose_name='销量')
    comments = models.IntegerField(default=0, verbose_name='评价数')
    desc_detail = models.TextField(default='', verbose_name='详细介绍')
    desc_pack = models.TextField(default='', verbose_name='包装信息')
    desc_service = models.TextField(default='', verbose_name='售后服务')

    class Meta:
        db_table = 'tb_spu'
        verbose_name = '商品SPU'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class SKU(BaseModel):
    """商品SKU"""
    name = models.CharField(max_length=50, verbose_name='名称')
    caption = models.CharField(max_length=100, verbose_name='副标题')
    spu = models.ForeignKey(SPU, on_delete=models.CASCADE, verbose_name='商品')
    category = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, verbose_name='从属类别')
    price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='单价')
    cost_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='进价')
    market_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='市场价')
    stock = models.IntegerField(default=0, verbose_name='库存')
    sales = models.IntegerField(default=0, verbose_name='销量')
    comments = models.IntegerField(default=0, verbose_name='评价数')
    is_launched = models.BooleanField(default=True, verbose_name='是否上架销售')
    default_image = models.ImageField(max_length=200, default='', null=True, blank=True, verbose_name='默认图片')

    class Meta:
        db_table = 'tb_sku'
        verbose_name = '商品SKU'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.id, self.name)


class SKUImage(BaseModel):
    """SKU图片"""
    sku = models.ForeignKey(SKU, on_delete=models.CASCADE, verbose_name='sku')
    image = models.ImageField(verbose_name='图片')

    class Meta:
        db_table = 'tb_sku_image'
        verbose_name = 'SKU图片'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s %s' % (self.sku.name, self.id)


class SPUSpecification(BaseModel):
    """商品SPU规格"""
    spu = models.ForeignKey(SPU, on_delete=models.CASCADE, related_name='specs', verbose_name='商品SPU')
    name = models.CharField(max_length=20, verbose_name='规格名称')

    class Meta:
        db_table = 'tb_spu_specification'
        verbose_name = '商品SPU规格'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s' % (self.spu.name, self.name)


class SpecificationOption(BaseModel):
    """规格选项"""
    spec = models.ForeignKey(SPUSpecification, related_name='options', on_delete=models.CASCADE, verbose_name='规格')
    value = models.CharField(max_length=20, verbose_name='选项值')

    class Meta:
        db_table = 'tb_specification_option'
        verbose_name = '规格选项'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s - %s' % (self.spec, self.value)


class SKUSpecification(BaseModel):
    """SKU具体规格"""
    sku = models.ForeignKey(SKU, related_name='specs', on_delete=models.CASCADE, verbose_name='sku')
    spec = models.ForeignKey(SPUSpecification, on_delete=models.PROTECT, verbose_name='规格名称')
    option = models.ForeignKey(SpecificationOption, on_delete=models.PROTECT, verbose_name='规格值')

    class Meta:
        db_table = 'tb_sku_specification'
        verbose_name = 'SKU规格'
        verbose_name_plural = verbose_name

    def __str__(self):
        return '%s: %s - %s' % (self.sku, self.spec.name, self.option.value)


class GoodsVisitCount(BaseModel):
    """统计分类商品访问量模型类"""
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='商品分类')
    count = models.IntegerField(verbose_name='访问量', default=0)
    date = models.DateField(auto_now_add=True, verbose_name='统计日期')

    class Meta:
        db_table = 'tb_goods_visit'
        verbose_name = '统计分类商品访问量'
        verbose_name_plural = verbose_name

而我们要传递的数据可以直接传递到数据库当中。

2、首页商品分类:

我们不难知道,首页商品的分类我们主要可以分三大类(第一类嵌套第二类,二类嵌套三类)。

当然数据库的内容我们也是按照如此形式,来关联三个大类的表的。

此时,在我们首页的视图当中,我们先对第一大类进行获取,其次二和三。关于具体的操作详细都在我的代码中有详细的介绍。

在下面代码中,获取完事三大类的商品数据后我们开始获取一些广告数据,方法也和上面一致。

from django.shortcuts import render
from django.views import View

from goods.models import GoodsChannel
from contents.models import ContentCategory,Content

class IndexView(View):
    '''
    响应首页
    '''
    def get(self , request):

        # 定义一个空的字典 , 存放商品分类的数据
        categories = {}
        # 查询商品分组的所有数据
        channels = GoodsChannel.objects.all()
        # 获取所有商品的分组
        for channel in channels:
            # 获取商品分组的 id , 作为分组字典的 key
            group_id = channel.group_id
            # 判断获取到的分组在字段中是否存在
            if group_id not in categories:
                categories[group_id] = {'channels':[] , 'sub_cats':[]}

            # 查询一级商品的数据信息
            # 根据商品的外键数据 , 判断是否为以及商品类别
            cat1 = channel.category
            categories[group_id]['channels'].append(
                {
                    'id':cat1.id,
                    'name':cat1.name,
                    'url' : channel.url
                }
            )
            # 获取二级商品类别数据
            # 二级的数据根据一级的类别 id 进行获取
            for cat2 in cat1.subs.all():
                cat2.sub_cat = []
                categories[group_id]['sub_cats'].append(
                    {
                        'id':cat2.id,
                        'name':cat2.name,
                        'sub_cat':cat2.sub_cat
                    }
                )
                # 获取三级数据
                for cat3 in cat2.subs.all():
                    cat2.sub_cat.append(
                        {
                            'id': cat3.id,
                            'name':cat3.name
                        }
                    )

        #首页商品推荐数据信息
        #获取到所有推荐商品的广告类别
        content_categories = ContentCategory.objects.all()
        contents = {}
        for content_category in content_categories:
            contents[content_category.key] = Content.objects.filter(
                category_id=content_category.id,
                status=True#是否展示
            ).all().order_by('sequence')#排序
        context = {'categories': categories, 'contents': contents}#要返回到前端的内容
        return render(request, 'index.html', context=context)




3、前端页面响应:

3.1、商品分类响应:

也就是要相应为下图这样的前端页面,根据我们创建的视图来响应。

<ul class="sub_menu">
                {% for group in categories.values %}
                    <li>
                        <div class="level1">
                            {% for channel in group.channels %}
                                <a href="{{ channel.url }}">{{ channel.name }}</a>
                            {% endfor %}
                        </div>
                        <div class="level2">
                            {% for cat2 in group.sub_cats %}
                                <div class="list_group">
                                    <div class="group_name fl">{{ cat2.name }} &gt;</div>
                                    <div class="group_detail fl">
                                        {% for cat3 in cat2.sub_cat %}
                                            <a href="/list/{{ cat3.id }}/1/">{{ cat3.name }}</a>
                                        {% endfor %}
                                    </div>
                                </div>
                            {% endfor %}
                        </div>
                    </li>
                {% endfor %}

3.2、转播图响应:

转播图我们响应时候注意拼接地址。

        <ul class="slide">
            {% for content in contents.index_lbt %}
                <li><a href="{{ content.url }}"><img src="/static/images/goods/{{ content.image }}.jpg" alt="幻灯片"></a>
                </li>
            {% endfor %}

3.3、三层内容分别响应:

第一层:

<div class="list_model">
            <div class="list_title clearfix">
                <h3 class="fl" id="model01">1F 手机通讯</h3>
                <div class="subtitle fr">
                    <a @mouseenter="f1_tab=1" :class="f1_tab===1?'active':''">时尚新品</a>
                    <a @mouseenter="f1_tab=2" :class="f1_tab===2?'active':''">畅想低价</a>
                    <a @mouseenter="f1_tab=3" :class="f1_tab===3?'active':''">手机配件</a>
                </div>
            </div>
            <div class="goods_con clearfix">
                <div class="goods_banner fl">
                    <img src="/static/images/goods/{{ contents.index_1f_logo.0.image.url }}.jpg">
                    <div class="channel">
                        {% for content in contents.index_1f_pd %}
                            <a href="{{ content.url }}">{{ content.title }}</a>
                        {% endfor %}
                    </div>
                    <div class="key_words">
                        {% for content in contents.index_1f_bq %}
                            <a href="{{ content.url }}">{{ content.title }}</a>
                        {% endfor %}
                    </div>
                </div>
                <div class="goods_list_con">
                    <ul v-show="f1_tab===1" class="goods_list fl">
                        {% for content in contents.index_1f_ssxp %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic">
                                    <img src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                    <ul v-show="f1_tab===2" class="goods_list fl">
                        {% for content in contents.index_1f_cxdj %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic">
                                    <img src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                    <ul v-show="f1_tab===3" class="goods_list fl">
                        {% for content in contents.index_1f_sjpj %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic">
                                    <img src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                </div>
            </div>
        </div>

第二层:

<div class="list_model model02">
            <div class="list_title clearfix">
                <h3 class="fl" id="model01">2F 电脑数码</h3>
                <div class="subtitle fr">
                    <a @mouseenter="f2_tab=1" :class="f2_tab===1?'active':''">加价换购</a>
                    <a @mouseenter="f2_tab=2" :class="f2_tab===2?'active':''">畅享低价</a>
                </div>
            </div>
            <div class="goods_con clearfix">
                <div class="goods_banner fl">
                    <img src="/static/images/goods/{{ contents.index_1f_logo.0.image.url }}.jpg">
                    <div class="channel">
                        {% for content in contents.index_2f_pd %}
                            <a href="{{ content.url }}">{{ content.title }}</a>
                        {% endfor %}
                    </div>
                    <div class="key_words">
                        {% for content in contents.index_2f_bq %}
                            <a href="{{ content.url }}">{{ content.title }}</a>
                        {% endfor %}
                    </div>
                </div>
                <div class="goods_list_con">
                    <ul v-show="f2_tab===1" class="goods_list fl">
                        {% for content in contents.index_2f_cxdj %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic"><img
                                        src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                    <ul v-show="f2_tab===2" class="goods_list fl">
                        {% for content in contents.index_2f_jjhg %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic"><img
                                        src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                </div>
            </div>
        </div>

第三层:

<div class="list_model model03">
            <div class="list_title clearfix">
                <h3 class="fl" id="model01">3F 家居家装</h3>
                <div class="subtitle fr">
                    <a @mouseenter="f3_tab=1" :class="f3_tab===1?'active':''">生活用品</a>
                    <a @mouseenter="f3_tab=2" :class="f3_tab===2?'active':''">厨房用品</a>
                </div>
            </div>
            <div class="goods_con clearfix">
                <div class="goods_banner fl">
                    <img src="/static/images/goods/{{ contents.index_1f_logo.0.image.url }}.jpg">
                    <div class="channel">
                        {% for content in contents.index_3f_pd %}
                            <a href="{{ content.url }}">{{ content.title }}</a>
                        {% endfor %}
                    </div>
                    <div class="key_words">
                        {% for content in contents.index_3f_bq %}
                            <a href="{{ content.url }}">{{ content.title }}</a>
                        {% endfor %}
                    </div>
                </div>
                <div class="goods_list_con">
                    <ul v-show="f3_tab===1" class="goods_list fl">
                        {% for content in contents.index_3f_shyp %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic"><img
                                        src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                    <ul v-show="f3_tab===2" class="goods_list fl">
                        {% for content in contents.index_3f_cfyp %}
                            <li>
                                <a href="{{ content.url }}" class="goods_pic"><img
                                        src="/static/images/goods/{{ content.image.url }}.jpg"></a>
                                <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                                <div class="price">{{ content.text }}</div>
                            </li>
                        {% endfor %}
                    </ul>
                </div>
            </div>
        </div>

3.4、快讯响应:

<div class="news">
    <div class="news_title">
        <h3>快讯</h3>
        <a href="#">更多 &gt;</a>
    </div>
    <ul class="news_list">
        {% for content in contents.index_kx %}
        <li><a href="{{ content.url }}">{{ content.title }}</a></li>
        {% endfor %}
    </ul>
    {% for content in contents.index_ytgg %}
    <a href="{{ content.url }}" class="advs"><img src="/static/images/goods/{{ content.image }}.jpg"></a>
    {% endfor %}
</div>

4、商品列表页:

如图,所谓商品列表页就是点击三级商品名称能够显示出具体的商品信息。

其中主要分为几大部分:

1、商品分类导航栏(也就是显示商品的三个级别信息)

2、具体商品(要分默认、价格、人气三部分)

4.1、优化:

因为在前面我们在获取三大级别的商品数据信息的时候我们是直接在响应首页的模型类里面进行的,但获取信息我们不仅是要在首页用到在后面很多地方都会用到比如商品分类导航栏,所以我们将获取商品三个级别信息的代码转移到content应用下的utils文件下:

from goods.models import  GoodsChannel
def get_categories():
    # 定义一个空的字典 , 存放商品分类的数据
    categories = {}
    # 查询商品分组的所有数据
    channels = GoodsChannel.objects.all()
    # 获取所有商品的分组
    for channel in channels:
        # 获取商品分组的 id , 作为分组字典的 key
        group_id = channel.group_id
        # 判断获取到的分组在字段中是否存在
        if group_id not in categories:
            categories[group_id] = {'channels': [], 'sub_cats': []}

        # 查询一级商品的数据信息
        # 根据商品的外键数据 , 判断是否为以及商品类别
        cat1 = channel.category
        categories[group_id]['channels'].append(
            {
                'id': cat1.id,
                'name': cat1.name,
                'url': channel.url
            }
        )
        # 获取二级商品类别数据
        # 二级的数据根据一级的类别 id 进行获取
        for cat2 in cat1.subs.all():
            cat2.sub_cat = []
            categories[group_id]['sub_cats'].append(
                {
                    'id': cat2.id,
                    'name': cat2.name,
                    'sub_cat': cat2.sub_cat
                }
            )
            # 获取三级数据
            for cat3 in cat2.subs.all():
                cat2.sub_cat.append(
                    {
                        'id': cat3.id,
                        'name': cat3.name
                    }
                )
    return categories

4.2、页面实现-导航栏:

实现这个页面我们无非就是:响应页面-实现商品分类导航栏-实现商品具体信息的提取-响应到前端。

对于实现商品分类导航栏我们的思路就是,当我们点击某级商品时候,我们会进入这个页面,而我们要响应出对应的三个级别的信息,那么我们同样的在goods应用下面找到utils文件进行获取。

from goods.models import GoodsCategory

def get_breadcrumd(category):
    # category 商品类别对象
    # 一级:breadcrumd = {cat1:''}
    # 二级:breadcrumd = {cat1:'' , cat2:''}
    # 三级:breadcrumd = {cat1:'' , cat2:'' , cat3:''}


    breadcrumd = {'cat1': '' , 'cat2': '' , 'cat3': ''}

    if category.parent == None:
        # 没有外键数据 , 说明类别为一级

        breadcrumd['cat1'] = category
    elif GoodsCategory.objects.filter(parent_id = category.id).count() == 0:
        #就是它的外键既不是空,且外键没有能与别的主键关联的,那就只能是第三级
        #第二级=第三级.外键
        #第一级=第二级.外键
        #二级数据的主键是有存在于外键,而三级数据的主键没外键与它关联
        # 判断是否有被链接 , 如果没有被链接说明是三级数据

        # 三级是通过二级数据连接获取一级的数据
        breadcrumd['cat3'] = category
        cat2 = category.parent
        breadcrumd['cat2'] = cat2
        breadcrumd['cat1'] = cat2.parent

    else:
        # 二级
        breadcrumd['cat1'] = category.parent
        breadcrumd['cat2'] = category

    return breadcrumd




就是它的外键既不是空,且外键没有能与别的主键关联的,那就只能是第三级,此时:第二级=第三级.外键,第一级=第二级.外键。二级数据的主键是有存在于外键,而三级数据的主键没外键与它关联
而此时的模型类:

class GoodsListView(View):
    '''
    商品列表页
    '''
    def get(self,request,category_id,page_num):
        #获取商品分类功能(获取到首页)
        categories=get_categories()

        #获取商品类别对象
        category=GoodsCategory.objects.get(id=category_id)
        '''
        这个就是因为响应具体数据时会发出get请求id,然后获取这个id的数据,
        为的就是下面能够按照这个数据将它的一级二级三级数据全部响应到页面上
        '''
        #调用列表导航栏(面包屑)
        breadcrumd=get_breadcrumd(category)

4.3、页面实现-商品具体信息:

我们设计的意图就这三类:按照默认(也就是按照时间排序)、价格(按照价格高低排序)、人气(按照购买数量排序)。

同样的是和上面的导航栏在同一模型类下继续写,因为同样的需要获取到这些数据。

class GoodsListView(View):
    '''
    商品列表页
    '''
    def get(self,request,category_id,page_num):
        #获取商品分类功能(获取到首页)
        categories=get_categories()

        #获取商品类别对象
        category=GoodsCategory.objects.get(id=category_id)
        '''
        这个就是因为响应具体数据时会发出get请求id,然后获取这个id的数据,
        为的就是下面能够按照这个数据将它的一级二级三级数据全部响应到页面上
        '''
        #调用列表导航栏(面包屑)
        breadcrumd=get_breadcrumd(category)

        #商品排序,也就是前端页面的默认价格人气那块(获取请求中的参数sort,获取商品排序的方式,若是没有sort参数,默认按照时间排序)
        sort=request.GET.get("sort","default")
        if sort=='price':
            sort_field='price'
        elif sort=='hot':
            sort_field = 'sales'
        else:
            sort='default'
            sort_field='create_time'
        #获取商品资源
        skus=SKU.objects.filter(is_launched=True,category_id=category_id).order_by(sort_field)#判断是否上架


        #制作分页器
        paginator=Paginator(skus,5)
        #获取当前页面的数据
        page_skus=paginator.page(page_num)
        #获取分页的总数
        total_num=paginator.num_pages

        context={
            'categories':categories,
            'breadcrumd':breadcrumd,
            'page_skus':page_skus,
            'total_num':total_num,
            'category_id':category_id,
            'page_num':page_num,
            'sort':sort,

        }
        return render(request,'list.html',context=context)

注意的一点,制作分页器也要相应到前端页面,具体的代码详细解释代码中都有注释。

4.4、前端页面响应:


相应导航栏,和上面相应的思路代码都一致。

<div class="sub_menu_con fl">
				<h1 class="fl">商品分类</h1>
				<ul class="sub_menu">
                {% for group in categories.values %}
                    <li>
                        <div class="level1">
                            {% for channel in group.channels %}
                                <a href="{{ channel.url }}">{{ channel.name }}</a>
                            {% endfor %}
                        </div>
                        <div class="level2">
                            {% for cat2 in group.sub_cats %}
                                <div class="list_group">
                                    <div class="group_name fl">{{ cat2.name }} &gt;</div>
                                    <div class="group_detail fl">
                                        {% for cat3 in cat2.sub_cat %}
                                            <a href="/list/{{ cat3.id }}/1/">{{ cat3.name }}</a>
                                        {% endfor %}
                                    </div>
                                </div>
                            {% endfor %}
                        </div>
                    </li>
                {% endfor %}
            </ul>
			</div>

响应商品数据信息:要注意的是关于照片地址的拼接。

			<ul class="goods_type_list clearfix">
                {% for sku in page_skus %}
				<li>
					<a href="{% url 'detail' sku.id %}"><img src="/static/images/goods/{{ sku.default_image.url }}.jpg/"></a>
					<h4><a href="{% url 'detail' sku.id %}">{{ sku.name }}</a></h4>
					<div class="operate">
						<span class="price">{{ sku.price }}</span>
						<span class="unit">台</span>
						<a href="#" class="add_goods" title="加入购物车"></a>
					</div>
				</li>
                {% endfor %}

对默认、价格、销量的响应:

<div class="r_wrap fr clearfix">
			<div class="sort_bar">
				<a href="{% url 'list' category_id page_num %}?sort=default"
                   {% if sort == 'default' %}class="active"{% endif %}>默认</a>
				<a href="{% url 'list' category_id page_num %}?sort=price"
                {% if sort == 'price' %}class="active"{% endif %}>价格</a>
				<a href="{% url 'list' category_id page_num %}?sort=hot"
                {% if sort == 'hot' %}class="active"{% endif %}>人气</a>
			</div>

分页器响应:注意分页器的响应要在底下导航信息前面

        <!-- 分页器盒子 -->
        <div class="pagenation">
            <div id="pagination" class="page"></div>
        </div>

#总结:

关于此篇博客小编主要介绍了关于在购物类项目关于商品具体信息如何响应的内容,其中最为主要的就是数据库和Django之间的来回调用,以及前端与后端之间的连接。小编后续还会继续更新后续内容,欢迎大家前来阅读!同时也欢迎大家点赞关注,您的支持将是小编变强的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RJ45空包弹网口描述与应用

RJ45空包弹网口&#xff0c;通常指的是RJ45接口的空芯线缆&#xff08;通常称为“空包”&#xff09;和相应的连接器。这种线缆和连接器组合常用于网络布线中&#xff0c;特别是在需要将网络信号从一端传输到另一端&#xff0c;同时保持信号完整性和隔离性的场合。 描述&#…

C++初阶:list的使用和模拟实现

关于list可以先看一下这个文档&#xff1a;list文档 一.list的介绍和使用 1.1 list的介绍 list实际上就是链表&#xff0c;是带头双向循环链表。 1.2 list的使用 list的使用跟我们以前用C语言实现时的一样。push&#xff0c;pop&#xff0c;insert等等。 1.2.1list的构造 …

【从零开始一步步学习VSOA开发】开发环境搭建

开发环境搭建 开发 VSOA 首先需要搭建开发环境&#xff0c;这里讲解 Windows 下 C/C 开发环境搭建方法。 下载 IDE 并申请授权码 SylixOS 的开发和部署需要 RealEvo-IDE 的支持&#xff0c;因此您需要先获取 RealEvo-IDE 的安装包和注册码。 RealEvo-IDE 分为体验版和商业版…

简单的 微服务netflix 学习

简单的 微服务netflix 学习 一.Eureka 学习 1. 服务简单搭建 1.1 首先确定pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-…

FPGA入门系列:计数器

目录 微信公众号获取更多FPGA相关源码&#xff0c;且微信公众号为首发&#xff0c;第一时间获取最新文章&#xff1a; 计数器是一种典型的时序器件&#xff0c;常用于对时钟脉冲的个数进行计数&#xff0c;还用于定时、分频、产生同步脉冲等 按触发方式分&#xff1a;同步计数…

国内SSL证书颁发机构哪家服务更优质?

SSL证书作为保障网站数据传输安全的关键工具&#xff0c;其重要性不言而喻。选择一个可靠的SSL证书代理商&#xff0c;不仅能够提供多样化的证书类型&#xff0c;而且能在众多品牌中进行比较&#xff0c;选择最适合自己的、性价比更高的产品。此外&#xff0c;优质的代理商还能…

JAVA项目基于Spring Boot的多媒体素材库

目录 一、前言 二、技术介绍 三、项目实现流程 四、论文流程参考 五、核心代码截图 专注于大学生实战开发、讲解和毕业答疑等辅导&#xff0c;获取源码后台 一、前言 信息化管理时代已至&#xff0c;计算机与互联网技术深度融合于生活点滴。本系统源于对用户需求的深刻洞…

Spark学习之SaprkCore

FlinkCore 1、JavaAPI 1、创建一个Topic并写入数据 向Kafka写数据 如果topic不存在则会自动创建一个副本和分区数都是1的topic package com.shujia.kafka;import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord…

JAVASpring学习Day2

面向切面编程 (AOP) 面向切面编程是一种编程范式&#xff0c;用于在程序中分离关注点&#xff0c;例如日志记录、事务管理和安全性。它主要由以下几个关键组成部分构成&#xff1a; 连接点 (Join Point)&#xff1a;在程序执行过程中可以插入切面的点&#xff0c;通常是方法的…

I2C 设备驱动编写流程

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、修改设备树1、 IO 修改或添加2、在 i2c1 节点追加 ap3216c 子节点3、查看设备树节点创建是否成功 二、AP3216C 驱动编写 前言 提示&#xff1a;这里可以添…

9.11 与 9.9 哪个大? 大模型幻觉从何而来?用最通俗的例子讲清楚大模型原理。

​如下图&#xff0c;我们使用用 gpt-4-turbo 模型为例&#xff0c;问9.11 与 9.9 哪个大&#xff0c;并让他一步一步给出分析步骤。你会发现&#xff0c;它开始了胡说八道&#xff0c;这就是“大模型幻觉” 。 那么问题来了&#xff0c;为什么会出现这种结果&#xff1f;幻觉从…

【Python代码】如何在多个Excel文件中高效找出含有特定关键词的文件?

点击上方"蓝字" 关注木易巷&#xff01; 哈喽&#xff0c;大家好&#xff0c;木易巷来啦&#xff01; 想象一下&#xff0c;如果你有一个文件夹&#xff0c;里面堆满了近百个Excel文件&#xff0c;你需要从中找出包含特定关键词文本的文件。文件格式不统一&#xf…

仓颉语言 -- 宏

使用新版本 &#xff08;2024-07-19 16:10发布的&#xff09; 1、宏的简介 宏可以理解为一种特殊的函数。一般的函数在输入的值上进行计算&#xff0c;然后输出一个新的值&#xff0c;而宏的输入和输出都是程序本身。在输入一段程序&#xff08;或程序片段&#xff0c;例如表达…

【OpenCV C++20 学习笔记】提取水平和垂直线条

提取水平和垂直线条 原理实操——去除五线谱的五线二进制化提取垂直对象完善边缘和最终输出图片黑白反转平滑 完整代码 其他图片元素提取实践提取水平线条提取音符轮廓 原理 在腐蚀和膨胀操作中&#xff0c;通过卷积核(kernel)&#xff0c;或者结构元素(structuring element)&…

vue-router核心TS类型

NavigationFailureType 枚举&#xff1a; export declare enum NavigationFailureType {/*** An aborted navigation is a navigation that failed because a navigation* guard returned false or called next(false)*/aborted 4,/*** A cancelled navigation is a navigati…

arduino程序-MC猜数字5、6(基础知识)

arduino程序-MC猜数字5、6&#xff08;基础知识&#xff09; 1-23 MC猜数字-5 自定义函数自定义函数自定义清理显示内容函数displayClear&#xff08;&#xff09;带参数函数displayNumber带参数、返回值的函数 1-24 MC猜数字-6 完成制作显示0~9数字函数改造产生随机数字函数改…

嵌入式人工智能(42-基于树莓派4B的红外遥控)

1、简介 红外遥控想必对大家来说都不陌生&#xff0c;红外也属于无线通信的一种&#xff0c;只要是无线通信&#xff0c;必然要用电磁波&#xff0c;要理解无线通信的本质和原理&#xff0c;不管用哪个频段都要学习电磁场与电磁波&#xff0c;这是一个难度很大的课&#xff0c…

IT事件经理在数字企业中的角色和责任

什么是IT事件经理&#xff1f; IT事件经理有时也被称为事件指挥官&#xff0c;他们承担着管理组织事件响应的总体责任&#xff0c;从委派各种事件响应任务到与每个利益相关者进行沟通和协调。 示例&#xff1a;当一个全球性的电子商务平台在一次销售活动中流量激增&#xff0c…

George Danezis谈Mysticeti的共识性能

Sui的新共识引擎Mysticeti已经在主网上开始分阶段推出。Mysten Labs联合创始人兼首席科学家George Danezis在采访中&#xff0c;讨论了其低延迟如何通过高性能应用程序提升用户体验。 采访视频&#xff1a; https://youtu.be/WHvtPQUa2Q0 中文译文&#xff1a;延迟和吞吐量对…

LSTM与GNN强强结合!全新架构带来10倍推理速度提升

今天来推荐一个深度学习领域很有创新性的研究方向&#xff1a;LSTM结合GNN。 GNN擅长处理图数据关系和特征&#xff0c;而LSTM擅长处理时间序列数据及长期依赖关系。通过将两者结合&#xff0c;我们可以有效提升时间序列预测的准确性和效率&#xff0c;尤其是在处理空间和时间…