页面静态化与定时任务

网站的首页频繁被访问,为了提升访问速度,除了缓存技术,还可以使用页面静态化技术。其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。

页面静态化

什么是页面静态化

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

页面中有些区域,因登录用户不同,而显示不同的数据,可以在用户请求完html页面后,通过ajax向后端发送请求,获取属于用户的特殊的数据。

首页配置静态化

在settings.py中添加保存静态文件的目录

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

front_end_pc为前端文件的存放目录

然后将静态化的页面数据例:index.html放置在templates文件里

静态化逻辑,生成静态化页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取要生成的数据
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扩展来实现。

1
pip install django-crontab

然后配置中添加应用

1
2
3
4
INSTALLED_APPS = [
...
'django_crontab', # 定时任务
]

设置任务的定时时间

1
2
3
4
5
# 定时任务
CRONJOBS = [
# 每5分钟执行一次生成主页静态文件
('*/5 * * * *', 'contents.crons.generate_static_index_html', '>> 日志路径/logs/crontab.log')
]

基本格式 :


分 时 日 月 周 命令

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

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

D:天(1-31)。

m: 月(1-12)。

d: 一星期内的天(0~6,0为星期天)

开启定时任务

1
python manage.py crontab add

显示已经激活的定时任务

1
python manage.py crontab show

移除定时任务

1
python manage.py crontab remove

解决中文字符问题

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

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

脚本手动生成静态化页面

为了开发方便,可以编写手动生成所有商品静态页面的脚本 在项目下新建包scripts,再创建regenerate_detail_html.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
#指定执行此py文件的命令为python
#/usr/bin/env表示在当前环境中查找python命令,当前为虚拟环境py3_django
"""
功能:手动生成所有SKU的静态detail html文件
使用方法:
./regenerate_detail_html.py
"""
import sys

sys.path.insert(0, '../')

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "meiduo_api.settings")

import django

django.setup()

from goods.models import SKU
# 异步任务执行静态化
from celery_tasks.html.tasks import generate_static_sku_detail_html

if __name__ == '__main__':
skus = SKU.objects.all()
for sku in skus:
print(sku.id)
generate_static_sku_detail_html(sku.id)