python学习之美多商城(十五):商品部分:页面静态化、定时任务(crontab模块)

一、页面静态化:

商场首页被频繁访问,为了提高访问速度,除了使用缓存技术外,还可以使用页面静态化技术。

页面静态化即动态渲染生成的页面结果保存成html文件,放到静态服务器中。用户访问的时候访问的直接是处理好的html静态文件。
对于页面中属于每个用户展示不同数据内容的部分, 可以在用户请求完静态化页面之后, 再页面中向后端发起请求,获取数据属于用户的特殊的数据。

1. 将首页静态化:

在广告内容应用contents中,新建一个crons.py文件(该文件会用于后面讲解的定时任务),在该文件中编写处理页面静态化的逻辑。

# meiduo_mall/apps/contents/crons.py
from collections import OrderedDict
from django.conf import settings
from django.template import loader
import os
import time

from goods.models import GoodsChannel
from .models import ContentCategory


def generate_static_index_html():
    """
    生成静态的主页html文件
    """
    print('%s: generate_static_index_html' % time.ctime())
    # 商品频道及分类菜单
    # 使用有序字典保存类别的顺序
    # categories = {
    #     1: { # 组1
    #         'channels': [{'id':, 'name':, 'url':},{}, {}...],
    #         'sub_cats': [{'id':, 'name':, 'sub_cats':[{},{}]}, {}, {}, ..]
    #     },
    #     2: { # 组2
    #
    #     }
    # }
    categories = OrderedDict()
    channels = GoodsChannel.objects.order_by('group_id', 'sequence')
    for channel in channels:
        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
        })
        # 构建当前类别的子类别
        for cat2 in cat1.goodscategory_set.all():
            cat2.sub_cats = []
            for cat3 in cat2.goodscategory_set.all():
                cat2.sub_cats.append(cat3)
            categories[group_id]['sub_cats'].append(cat2)

    # 广告内容
    contents = {}
    content_categories = ContentCategory.objects.all()
    for cat in content_categories:
        contents[cat.key] = cat.content_set.filter(status=True).order_by('sequence')

    # 渲染模板
    context = {
        'categories': categories,
        'contents': contents
    }
    template = loader.get_template('index.html')
    html_text = template.render(context)
    file_path = os.path.join(settings.GENERATED_STATIC_HTML_FILES_DIR, 'index.html')
    with open(file_path, 'w', encoding='utf-8') as f:
        f.write(html_text)

在配置文件中添加生成静态文件的保存路径:

# meiduo_mall/settings/dev.py
#coding=utf-8

...
# 生成静态html文件保存目录
GENERATED_STATIC_HTML_FILES_DIR = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'front_end_pc')

在meiduo_mall中新建templates模板目录,配置模板目录

# meiduo_mall/settings/dev.py
...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
...

在模板目录中新建index.html模板文件

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>美多商城-首页</title>
    <link rel="stylesheet" type="text/css" href="css/reset.css">
    <link rel="stylesheet" type="text/css" href="css/main.css">
    <script type="text/javascript" src="js/host.js"></script>
    <script type="text/javascript" src="js/vue-2.5.16.js"></script>
    <script type="text/javascript" src="js/axios-0.18.0.min.js"></script>
    <script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="js/slide.js"></script>
</head>
<body>
    <div id="app" v-cloak>
    <div class="header_con">
        <div class="header">
            <div class="welcome fl">欢迎来到美多商城!</div>
            <div class="fr">
                <div v-if="username" class="login_btn fl">
                    欢迎您:<em>[[ username ]]</em>
                    <span>|</span>
                    <a @click="logout">退出</a>
                </div>
                <div v-else class="login_btn fl">
                    <a href="login.html">登录</a>
                    <span>|</span>
                    <a href="register.html">注册</a>
                </div>
                <div class="user_link fl">
                    <span>|</span>
                    <a href="user_center_info.html">用户中心</a>
                    <span>|</span>
                    <a href="cart.html">我的购物车</a>
                    <span>|</span>
                    <a href="user_center_order.html">我的订单</a>
                </div>
            </div>
        </div>
    </div>

    <div class="search_bar clearfix">
        <a href="index.html" class="logo fl"><img src="images/logo.png"></a>
        <div class="search_wrap fl">
            <form method="get" action="/search.html" class="search_con">
                <input type="text" class="input_text fl" name="q" placeholder="搜索商品">
                <input type="submit" class="input_btn fr" name="" value="搜索">
            </form>
            <ul class="search_suggest fl">
                <li><a href="#">索尼微单</a></li>
                <li><a href="#">优惠15元</a></li>
                <li><a href="#">美妆个护</a></li>
                <li><a href="#">买2免1</a></li>
            </ul>
        </div>

        <div class="guest_cart fr">
            <a href="#" class="cart_name fl">我的购物车</a>
            <div class="goods_count fl" id="show_count">15</div>

            <ul class="cart_goods_show">
                <li>
                    <img src="images/goods/goods001.jpg" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>4</div>
                </li>
                <li>
                    <img src="images/goods/goods002.jpg" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>5</div>
                </li>
                <li>
                    <img src="images/goods/goods003.jpg" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>6</div>
                </li>
                <li>
                    <img src="images/goods/goods003.jpg" alt="商品图片">
                    <h4>商品名称手机</h4>
                    <div>6</div>
                </li>
            </ul>            
        </div>
    </div>

    <div class="navbar_con">
        <div class="navbar">
            <h1 class="fl">商品分类</h1>
            <ul class="navlist fl">
                <li><a href="">首页</a></li>
                <li class="interval">|</li>
                <li><a href="">真划算</a></li>
                <li class="interval">|</li>
                <li><a href="">抽奖</a></li>
            </ul>
        </div>
    </div>

    <div class="pos_center_con clearfix">
        <ul class="slide">
            {% for content in contents.index_lbt %}
            <li><a href="{{ content.url }}"><img src="{{ content.image.url }}" alt="{{ content.title }}"></a></li>
            {% endfor %}
        </ul>
        <div class="prev"></div>
        <div class="next"></div>
        <ul class="points">
            <!-- <li class="active"></li>
            <li></li>
            <li></li>
            <li></li> -->
        </ul>
        <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.html?cat={{cat3.id}}">{{cat3.name}}</a>
                            {% endfor %}
                        </div>
                    </div>
                    {% endfor %}
                </div>
            </li>
            {% endfor %}
        </ul>

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

    <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.url }}">
                <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>
            <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.url }}"></a>
                    <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                    <div class="prize">{{ 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.url }}"></a>
                    <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                    <div class="prize">{{ 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.url }}"></a>
                    <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                    <div class="prize">{{ content.text }}</div>
                </li>
                {% endfor %}
            </ul>
        </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="{{ contents.index_2f_logo.0.image.url}}">
                    <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>
                <ul v-show="f2_tab===1" class="goods_list fl">
                    {% for content in contents.index_2f_jjhg %}
                    <li>
                        <a href="{{ content.url }}" class="goods_pic"><img src="{{ content.image.url }}"></a>
                        <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                        <div class="prize">{{ content.text }}</div>
                    </li>
                    {% endfor %}
                </ul>
                <ul v-show="f2_tab===2" class="goods_list fl">
                    {% for content in contents.index_2f_cxdj %}
                    <li>
                        <a href="{{ content.url }}" class="goods_pic"><img src="{{ content.image.url }}"></a>
                        <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                        <div class="prize">{{ content.text }}</div>
                    </li>
                    {% endfor %}
                </ul>
            </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="{{ contents.index_3f_logo.0.image.url }}">
                    <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>
                <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.url }}"></a>
                        <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                        <div class="prize">{{ 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.url }}"></a>
                        <h4><a href="{{ content.url }}" title="{{ content.title }}">{{ content.title }}</a></h4>
                        <div class="prize">{{ content.text }}</div>
                    </li>
                    {% endfor %}
                </ul>
            </div>
        </div>

    <div class="footer">
        <div class="foot_link">
            <a href="#">关于我们</a>
            <span>|</span>
            <a href="#">联系我们</a>
            <span>|</span>
            <a href="#">招聘人才</a>
            <span>|</span>
            <a href="#">友情链接</a>
        </div>
        <p>CopyRight © 2016 北京美多商业股份有限公司 All Rights Reserved</p>
        <p>电话:010-****888    京ICP备*******8号</p>
    </div>
    </div>
    <script type="text/javascript" src="js/index.js"></script>
</body>
</html>

二、定时任务:

对于首页的静态化,考虑到页面的数据可能由多名运营人员维护,并且经常变动,所以将其做成定时任务,即定时执行静态化。

在Django执行定时任务,可以通过django-crontab扩展来实现。

1.安装

pip install django-crontab

2.添加应用

# meiduo_mall/settings/dev.py

INSTALLED_APPS = [
    ...
    'django_crontab',  # 定时任务
    ...
]

3.设置任务的定时时间

在配置文件中设置定时执行的时间
每个定时任务分为三部分定义:

  • 任务时间
基本格式 :
 * * * * *
分 时 日 月 周      命令

M: 分钟(0-59)。每分钟用*或者 */1表示

H:小时(0-23)。(0表示0点)

D:天(1-31)。

m: 月(1-12)。

d: 一星期内的天(0~6,0为星期天)。
  • 任务方法

  • 任务日志

首页的定时任务设置如下

# meiduo_mall/settings/dev.py

# 定时任务
CRONJOBS = [
    # 每5分钟执行一次生成主页静态文件
    ('*/5 * * * *', 'contents.crons.generate_static_index_html', '>> /Users/delron/Desktop/meiduo_mall/logs/crontab.log')
]

4.解决中文字符问题:

在定时任务中,如果出现非英文字符,会出现字符异常错误
在这里插入图片描述
可以通过在配置文件中添加定时任务执行的附加命令来实现

# meiduo_mall/settings/dev.py

# 解决crontab中文问题
CRONTAB_COMMAND_PREFIX = 'LANG_ALL=zh_cn.UTF-8'

5.开启定时任务

  • 添加定时任务到系统中
python manage.py crontab add
  • 显示已经激活的定时任务
python manage.py crontab show
  • 移除定时任务
python manage.py crontab remove
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浅弋、璃鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值