django 实现定时任务

页面静态化

商城的首页频繁被访问,为了提升访问速度,除了我们之前已经学过的使用缓存技术外,还可以使用页面静态化技术。

页面静态化即将动态渲染生成的页面结果保存成html文件,放到静态文件服务器中。用户访问的时候访问的直接是处理好之后的html静态文件。

对于页面中属于每个用户展示不同数据内容的部分,可以在用户请求完静态化之后的页面后,在页面中向后端发送请求,获取属于用户的特殊的数据。

我们现在将首页进行页面静态化处理。

在广告内容应用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)

定时任务

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

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

安装

pip install django-crontab

添加应用

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

设置任务的定时时间

在配置文件中设置定时执行的时间

每个定时任务分为三部分定义:

  • 任务时间

    基本格式 :
    
    * * * * *
    
    分 时 日 月 周      命令
    
    M: 分钟(0-59)。每分钟用*或者 */1表示
    
    H:小时(0-23)。(0表示0点)
    
    D:天(1-31)。
    
    m: 月(1-12)。
    
    d: 一星期内的天(0~6,0为星期天)。
    
  • 任务方法

  • 任务日志

首页的定时任务设置如下

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

解决中文字符问题

在定时任务中,如果出现非英文字符,会出现字符异常错误

crontab错误

可以通过在配置文件中添加定时任务执行的附加命令来实现

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

开启定时任务

添加定时任务到系统中

python manage.py crontab add

显示已经激活的定时任务

python manage.py crontab show

移除定时任务

python manage.py crontab remove

猜你喜欢

转载自blog.csdn.net/qwe0ytr/article/details/89323257