电商类项目-展示首页商品频道分类

发布时间 2023-06-28 17:02:12作者: 清安宁
  • 参考网址
- https://blog.csdn.net/weixin_45905671/article/details/115052054
  • 页面展示

  • 数据响应如下
{
    "1":{ // 数字编号表示'组号',即对'一级目录'进行分组
        "channels":[ // 一级目录
            {"id":1, "name":"手机", "url":"http://shouji.jd.com/"},
            {"id":2, "name":"相机", "url":"http://www.baidu.cn/"}
        ],
        "sub_cats":[
            {
                "id":38, 
                "name":"手机通讯",  // 二级目录
                "sub_cats":[
                    {"id":115, "name":"手机"}, // 三级目录
                    {"id":116, "name":"游戏手机"}
                ]
            },
            {
                "id":39, 
                "name":"手机配件", // 二级目录
                "sub_cats":[
                    {"id":119, "name":"手机壳"},// 三级目录
                    {"id":120, "name":"贴膜"}
                ]
            }
        ]
    },
    "2":{
        "channels":[],
        "sub_cats":[]
    }
}

  • 需要两张表来支持以上数据,表模型如下
### models.py

class GoodsCategory(BaseModel):
    """
    商品类别(分组)
    """
    name = models.CharField(max_length=10, verbose_name='名称')
    parent = models.ForeignKey('self', 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 GoodsChannel(BaseModel):
    """
    商品频道
    """
    group_id = models.IntegerField(verbose_name='组号')
    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
  • 视图逻辑如下: 要查询数据库,把数据手动拼接成上述结构返回给前端
### views

from django.shortcuts import render
from django.views import View
from goods.models import GoodsCategory, GoodsChannel
from collections import OrderedDict


class IndexView(View):
    """首页广告"""

    def get(self, request):
        """提供首页页面"""
        # 查询并展示商品分类

        # categories = {}  # 优化 OrderedDict 由无序变成有序
        categories = OrderedDict()
        # 查询所有的商品频道
        channels = GoodsChannel.objects.order_by('group_id', 'sequence')

        for channel in channels:
            # 37个频道 11个组
            group_id = channel.group_id
            # print(group_id)
            if group_id not in categories:
                categories[group_id] = {'channels': [], 'sub_cats': []}

            # print(categories)
            cat1 = channel.category
            categories[group_id]['channels'].append(
                {
                    "id": cat1.id,
                    "name": cat1.name,
                    "url": channel.url
                }
            )
            # print(categories)  # 打印结果一级分类完成
            # 查询二级和三级类别
            # 查询二级 parent_id = cat1.id
            # for cat2 in cat1.subs.all():  此行简写代码可替换下面一行代码  models.py中定义了related_name=subs
            for cat2 in GoodsCategory.objects.filter(parent_id=cat1.id).all():
                cat2.sub_cats = []
                categories[group_id]["sub_cats"].append(
                    {
                        "id": cat2.id,
                        "name": cat2.name,
                        "sub_cats": cat2.sub_cats
                    }
                )

                # for cat3 in cat2.subs.all():
                for cat3 in GoodsCategory.objects.filter(parent_id=cat2.id).all():
                    cat2.sub_cats.append(
                        {
                            "id": cat3.id,
                            "name": cat3.name,
                        }
                    )
        print(categories)

        '''
        {
            "1":{
                "channels":[
                    {"id":1, "name":"手机", "url":"http://shouji.jd.com/"},
                    {"id":2, "name":"相机", "url":"http://www.baidu.cn/"}
                ],
                "sub_cats":[
                    {
                        "id":38, 
                        "name":"手机通讯", 
                        "sub_cats":[
                            {"id":115, "name":"手机"},
                            {"id":116, "name":"游戏手机"}
                        ]
                    },
                    {
                        "id":39, 
                        "name":"手机配件", 
                        "sub_cats":[
                            {"id":119, "name":"手机壳"},
                            {"id":120, "name":"贴膜"}
                        ]
                    }
                ]
            },
        '''
        context = {
            "categories": categories
        }
        return render(request, 'index.html', context=context)


  • 前端页面
<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_cats %}
								<a href="/list/{{ cat3.id }}/1/">{{ cat3.name }}</a>
								{% endfor %}
							</div>
						</div>
						{% endfor %}
					</div>
				</li>
				{% endfor %}
</ul>