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
Django提供了多种方式来实现定时任务功能,以下是其中两种常用的方式: 1. 使用Django自带的定时任务框架——Django Q Django Q是一个基于Django的异步任务处理库,它提供了一种简单的方式来实现定时任务功能。 首先,在settings.py文件中添加以下配置: ``` INSTALLED_APPS = [ ... 'django_q', ] Q_CLUSTER = { 'name': 'DjangORM', 'workers': 4, 'timeout': 180, 'retry': 3600, 'queue_limit': 50, 'bulk': 10, 'orm': 'default' } ``` 然后,在项目中的任何位置,都可以使用以下代码来定义一个定时任务: ``` from django_q.tasks import async_task from datetime import datetime, timedelta def my_task(): # 定时任务的具体业务逻辑 pass # 设置任务执行时间 run_date = datetime.now() + timedelta(minutes=1) # 异步执行定时任务 async_task(my_task, schedule=run_date) ``` 这样,我们就可以通过上面的代码来实现一个1分钟后执行的定时任务。 2. 使用第三方定时任务库——APScheduler APScheduler是一个Python的第三方定时任务库,它支持多种调度方式,包括简单的定时执行、循环执行、按天、按周等方式。 首先,在项目中安装APScheduler: ``` pip install apscheduler ``` 然后,在Django中的任何位置,都可以使用以下代码来定义一个定时任务: ``` from apscheduler.schedulers.background import BackgroundScheduler from datetime import datetime, timedelta def my_task(): # 定时任务的具体业务逻辑 pass # 创建一个后台调度器 scheduler = BackgroundScheduler() # 设置任务执行时间 run_date = datetime.now() + timedelta(minutes=1) # 添加定时任务 scheduler.add_job(my_task, 'date', run_date=run_date) # 启动调度器 scheduler.start() ``` 这样,我们就可以通过上面的代码来实现一个1分钟后执行的定时任务。需要注意的是,调度器需要在Django启动后才能正常运行,因此最好将调度器的启动代码放在Django的启动脚本中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值