700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > HTML页面静态化技术

HTML页面静态化技术

时间:2021-05-17 00:53:56

相关推荐

HTML页面静态化技术

随着网站的内容的增多和用户访问量的增多,无可避免的是网站加载会越来越慢,受限于带宽和服务器同一时间的请求次数的限制,我们往往需要在此时对我们的网站进行代码优化和服务器配置的优化。

此文已Django的电商网站为例(处理高并发问题)

技术点:首页静态化,详情页面静态化,定时任务,异步任务

所谓的静态化技术就是 将查询好的数据填充到模板中,然后将生成的html写入到指定的文件中

静态处理后又给网站带来了哪些好处?

静态页面相对于动态页面更容易被搜索引擎收录。访问静态页面不需要经过程序处理,因此可以提高运行速度。减轻服务器负担。HTML页面不会受Asp相关漏洞的影响。

分析需求:

1.首页频繁被访问 ,经常需要更新,发生变化,页面只有一个(用定时任务处理,定时刷新)

2.详情页面页面多,只有在数据发生变化时才需要更新页面(需要生成的静态化页面多,用celery处理)

前期配置:

需要在Django的setting.py文件中添加模板路径

修改成:

'DIRS': [os.path.join(BASE_DIR, 'templates')],

添加文件保存路径

DEFAULT_FILE_STORAGE = 'utils.fastdfs.fdfsstorage.FastDFSStorage'

在项目中创建templates文件夹

注意创建的路径,如果路径创建错误,会一直报Templates DoesNotExist的错误

此时可以找一个test.py

import osfrom mall.settings import BASE_DIRurl = [os.path.join(BASE_DIR, 'templates')]print(url)

输出一下路径看路径是否正确

在templates文件夹中创建home.html,index.html和detail.html并添加对应的前端代码

获取到前端和详情页面的数据,保证能正常访问

首页:(分类数据和首页数据)

静态化:

1.获取到模板

2.将数据渲染到模板中

3.需要将html数据写入指定的文件中

template = loader.get_template('index.html')html_data = template.render(context)#将文件写入file_path = os.path.join(settings.GENERATED_STATIC_HTML_FILES_DIR,'index.html')with open(file_path,'w') as f:f.write(html_data)

添加静态化首页的手动脚本test_script.py文件

#!/usr/bin/env pythonimport syssys.path.insert(0, '../')sys.path.insert(0, '../apps')import osif not os.getenv('DJANGO_SETTINGS_MODULE'):os.environ['DJANGO_SETTINGS_MODULE'] = 'mall.settings'# 让django进行初始化设置import djangodjango.setup()from contents.crons import generate_static_index_htmlif __name__ == '__main__':generate_static_index_html()

给脚本文件添加可执行权限: chmod +xtest_script.py

但是像网站通常都会常常需要更新像推荐商品等信息,我们不能每次在定点让人生成静态文件

此时可以利用定时任务

安装: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为星期天)。

在setting.py中添加

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

执行脚本文件:./test_script.py

此时首页静态化页面创建成功

在/home/python/Desktop/meiduo/mall/logs/crontab.log文件中可以看到

Wed Aug 29 22:17:01 :generate_static_indexWed Aug 29 22:18:02 :generate_static_index

详情页面

1.详情页面需求时项目上线先静态化生成全部的页面

2.然后在后台管理系统每次更改数据的时候重新生成静态化页面

在celery_tasks中新建html/tasks.py任务

import osfrom celery_tasks.main import appfrom utils.goods import get_categoriesfrom django.template import loaderfrom django.conf import settingsfrom goods.models import Goods,SKU@app.task(name='generate_static_sku_detail_html')def generate_static_sku_detail_html(sku_id):# 获取分类数据categories = get_categories()# 获取当前商品数据sku = SKU.objects.get(id=sku_id)sku.images = sku.skuimage_set.all()# 获取面包屑数据goods = sku.goodsgoods.channel = goods.category1.goodschannel_set.all()[0]# 获取商品规格项idssku_key = []sku_specs = sku.skuspecification_set.order_by('spec_id')for sku_spec in sku_specs:sku_key.append(sku_spec.option.id)# 构建商品规格# 获取所有商品,skus = goods.sku_set.all()# 构建不同规格参数(选项)的sku字典# spec_sku_map = {#(规格1参数id, 规格2参数id, 规格3参数id, ...): sku_id,#(规格1参数id, 规格2参数id, 规格3参数id, ...): sku_id,#...# }spec_sku_map = {}for s in skus:s_peces = sku.skuspecification_set.order_by('spec_id')# 用于记录 规格参数idkey = []for spec in s_peces:key.append(spec.option.id)# 添加数据spec_sku_map[tuple(key)] = s.id# 获取当前商品的规格信息# specs = [# {# 'name': '屏幕尺寸',# 'options': [# {'value': '13.3寸', 'sku_id': xxx},# {'value': '15.4寸', 'sku_id': xxx},# ]# },# {# 'name': '颜色',# 'options': [# {'value': '银色', 'sku_id': xxx},# {'value': '黑色', 'sku_id': xxx}# ]# },# ...# ]specs = goods.goodsspecification_set.order_by('id')# 若当前sku的规格信息不完整,则不再继续if len(sku_key) < len(specs):return# 针对于商品数据进行遍历for index, spec in enumerate(specs):# 复制当前sku的规格键key = sku_key[:]# 该规格的选项options = spec.specificationoption_set.all()for option in options:# 在规格参数sku字典中查询符合当前规则的skukey[index] = option.idoption.sku_id = spec_sku_map.get(tuple(key))spec.options = options# 组织上下文context = {'categories': categories,'goods': goods,'specs': specs,'sku': sku}template = loader.get_template('detail.html')html_text = template.render(context)file_path = os.path.join(settings.GENERATED_STATIC_HTML_FILES_DIR, 'goods/' + str(sku_id) + '.html')with open(file_path, 'w') as f:f.write(html_text)

重新执行celery

celery -A celery_tasks.main worker -l info

在front文件夹中,创建一个 goods文件夹

1.需要创建test2_script.py脚本文件

import syssys.path.insert(0, '../')sys.path.insert(0, '../mall/apps')import osif not os.getenv('DJANGO_SETTINGS_MODULE'):os.environ['DJANGO_SETTINGS_MODULE'] = 'mall.settings'import djangodjango.setup()from django.template import loaderfrom django.conf import settingsfrom utils.goods import get_categoriesfrom goods.models import SKUdef generate_static_sku_detail_html(sku_id):"""生成静态商品详情页面"""# 商品分类菜单categories = get_categories()# 获取当前sku的信息sku = SKU.objects.get(id=sku_id)sku.images = sku.skuimage_set.all()# 面包屑导航信息中的频道goods = sku.goodsgoods.channel = goods.category1.goodschannel_set.all()[0]# 构建当前商品的规格键sku_specs = sku.skuspecification_set.order_by('spec_id')sku_key = []for spec in sku_specs:sku_key.append(spec.option.id)# 获取当前商品的所有SKUskus = goods.sku_set.all()# 构建不同规格参数(选项)的sku字典# spec_sku_map = {#(规格1参数id, 规格2参数id, 规格3参数id, ...): sku_id,#(规格1参数id, 规格2参数id, 规格3参数id, ...): sku_id,#...# }spec_sku_map = {}for s in skus:# 获取sku的规格参数s_specs = s.skuspecification_set.order_by('spec_id')# 用于形成规格参数-sku字典的键key = []for spec in s_specs:key.append(spec.option.id)# 向规格参数-sku字典添加记录spec_sku_map[tuple(key)] = s.id# 获取当前商品的规格信息specs = goods.goodsspecification_set.order_by('id')# 若当前sku的规格信息不完整,则不再继续if len(sku_key) < len(specs):returnfor index, spec in enumerate(specs):# 复制当前sku的规格键key = sku_key[:]# 该规格的选项options = spec.specificationoption_set.all()for option in options:# 在规格参数sku字典中查找符合当前规格的skukey[index] = option.idoption.sku_id = spec_sku_map.get(tuple(key))spec.options = options# 渲染模板,生成静态html文件context = {'categories': categories,'goods': goods,'specs': specs,'sku': sku}template = loader.get_template('detail.html')html_text = template.render(context)file_path = os.path.join(settings.GENERATED_STATIC_HTML_FILES_DIR, 'goods/' + str(sku_id) + '.html')with open(file_path, 'w') as f:f.write(html_text)if __name__ == '__main__':skus = SKU.objects.all()for sku in skus:print(sku.id)generate_static_sku_detail_html(sku.id)

给文件添加可执行权限: chmod +xtest2_script.py

执行脚本文件:./test2_script.py

2.修改数据时调用异步任务需要重写save_model方法

例如:

from . import modelsclass SKUAdmin(admin.ModelAdmin):def save_model(self, request, obj, form, change):obj.save()from celery_tasks.html.tasks import generate_static_sku_detail_htmlgenerate_static_sku_detail_html.delay(obj.id)

全部添加成功后,在admin管理页面中修改数据后,就会调用异步任务重新生成静态化文件了

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。