Django项目实践(商城):十四、首页广告

在这里插入图片描述

(根据居然老师直播课内容整理)

一、展示首页商品频道分类

1、首页商品频道分类数据结构分析

在这里插入图片描述

  • 现在要将页面显示成类似上图;
  • 数据展示的结构如下:(结构不是固定的,按项目需求而来)
    (一张三级联动的表 是通过parent_id来做的)
{
    
    
    "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":[]
    }
}

  • 这是一个json类型数据
  • “1”:是组,共有11个
  • “channels” 频道 一共是37个频道 下图频道展示了两个频道,频道下面还有二级“sub_cats”, "sub_cats"里面的"sub_cats"是一个三级分类,需要查询数据库,把数据拼接成下图结构给前端返回,前端接收到数据就可以显示到页面中来。
    在这里插入图片描述

2、后端代码实现

  • 定一个空的有序字典categories
  • 查询所有的商品频道,按组号id 和 顺序号sequence 排序
  • 对37个频道进行循环处理
    • 取出组号
    • 判断组号是否在categories中, 即是否登记过(37个频道只有11个组,频道会重复)
    • 如果组id 不在 categories中,有序字典categories 增加一条记录,其中频道列表和sub_cats列表为空
    • 根据频道对象获得对应的一级类别对象cat1
    • 对有序字典categories的频道列表中添加频道信息
    • 查询出cat1.id为parent_id的所有二级类别数据,并循环取出每一个二级类别对象cat2
      • 将空列表赋值组cat2对象的sub_cat属性
      • 对有序字典categories的sub_cats列表中添加频二级类别信息,并将cat2.sub_cat赋值给该对象的sub_cats
      • 查询出cat2.id为parent_id的所有三级类别数据,并循环取出每一个三级类别对象cat3,并将cat3的信息组成的字典,添加到cat2.sub_cat列表中
  • 至此,首页商品频道分类的json数据就已生成,将此数据按前端要求组成字典
  • 返回首页html,带上商品频道分类的json数据(字典)
# apps/contents/views.py
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)

3、前端页面实现

		<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>

二、查询所有的首页广告

  • 数据库设计时,将首页广告分成不同类别,广告内容也统一格式存放
    在这里插入图片描述
  • 将所有广告按类别按格式发送组前端进行展示

1、首页广告数据结构分析

在这里插入图片描述

  • 这是一个json的格式
    • 以广告类别中key字段的值为字典的key,字典value 是 该类别广告内容组成的字典为元素的列表
  • 如上图:index_lbt 是 广告类别表中 轮播图key字段的值
    在这里插入图片描述
  • 广告内容表中 美图 和 黑色星期五 的 类别id = 1
    在这里插入图片描述

2、后端代码实现

  • 查询所有广告类别
  • 循环遍历所有广告类别
    • 通过广告类别id查询该类别所有广告信息,排除不展示的,按显示顺序排序
    • 用广告类别字段key的值为字典key,字典value为该类别所有广告信息字典组成的列表
  • 将得到的字典按格式保存到前端数据集中
class IndexView(View):
    """商城首页"""

    def get(self,request):
        """提供首页页面"""

        # 查询并展示商品分类
		......

		# 查询所有的首页广告

        # 查询所有广告类别
        context_categories = ContentCategory.objects.all()
        contents = {
    
    }

        for context_category in context_categories:
            # temp1 = Content.objects.filter(category_id=context_category.id, status=True).all().order_by("sequence")
            # print(type(temp1))
            contents[context_category.key]=Content.objects.filter(category_id=context_category.id,status=True).all().order_by("sequence")

        # print(contents)

        context = {
    
    
            "categories": categories,
            'contents': contents,
        }
        return render(request, 'index.html', context=context)

3、前端页面实现

3.1 轮播图广告

<ul class="slide">
    {% for content in contents.index_lbt %}
    <li><a href="{
     
     { content.url }}"><img src="{
     
     { content.image }}" alt="{
     
     { content.title }}"></a></li>
    {% endfor %}
</ul>

3.2 快讯和页头广告

<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="{
     
     { content.image }}"></a>
    {% endfor %}
</div>

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="{
     
     { contents.index_1f_logo.0.image}}">
            <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="{
     
     { content.image }}"></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="{
     
     { content.image }}"></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="{
     
     { content.image }}"></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="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="{
     
     { contents.index_2f_logo.0.image}}">
            <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="{
     
     { content.image }}"></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="{
     
     { content.image }}"></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.5 楼层广告(三楼)

<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="{
     
     { contents.index_3f_logo.0.image }}">
            <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="{
     
     { content.image }}"></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="{
     
     { content.image }}"></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>

4、功能完善

  • 完成以上操作,页面图片不能打开:
    在这里插入图片描述

  • 结论:

    • 通过FastDFS上传文件后返回的’Remote file_id’字段是文件索引。
    • 文件索引会被我们存储到MySQL数据库。所以将来读取出来的也是文件索引,导致界面无法下载到图片。
  • 解决方法:

    • 重写Django文件存储类的url()方法。
    • 在重写时拼接完整的图片下载地址(协议、IP、端口、文件索引)
    • 详见《Django项目实践(商城):十四、补充:Django文件存储类url()》
    • 切记,image后面加url

猜你喜欢

转载自blog.csdn.net/laoluobo76/article/details/115149386