- 目的:网站本身性能的优化,减少数据库的查询次数.
- 防止恶意的攻击.DDOS攻击
页面静态化
把数据库查询到的内容,写入到静态index.html页面(利用celery异步)
cdlery_tasks/tasks.py
定义一个任务:
from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner
@app.task
def generate_static_index_html():
'''首页'''
# 获取商品的种类信息
types = GoodsType.objects.all()
for type in types:
print('*******商品分类名称:' + type.name)
# 获取首页轮播商品信息
goods_banners = IndexGoodsBanner.objects.all().order_by('index')
# 获取首页促销活动信息
promotion_banners = IndexPromotionBanner.objects.all().order_by('index')
# 获取首页分类商品展示信息
# type_goods_banners = IndexTypeGoodsBanner.objects.all()
# 获取美各种累信息
for type in types: # GoodsType
# 获取type种类首页分类商品的图片的展示信息
image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')
# 获取type种类首页分类商品的文字展示信息
title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
# 动态给type增加属性,分别保存首页分类商品的图片展示信息和文字展示信息
type.image_banners = image_banners
type.title_banners = title_banners
# 组织模板上下文
context = {'types': types,
'goods_banners': goods_banners,
'promotion_banners': promotion_banners
}
# 使用模板
# 1加载模板
temp = loader.get_template(('static_index.html'))
# 2定义上下文
# context = RequestContext(request, context) #没有request所以忽略
# 模板渲染
static_index_html = temp.render(context)
# 生成首页静态文件
save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
print(save_path)
with open(save_path, 'w') as f:
f.write(static_index_html)
基本与动态显示页面方法一样,只不过在代码后半部分,写一个 write方法,把首页信息,写入文件.注意,这个文件写在 任务处理者目录下面.
nginx配置
去修改任务处理者所在电脑的nginx配置文件,server 80端口,内容:
sudo vi /usr/local/nginx/conf/nginx.conf
在server 80端口添加如下 location的配置
server {
listen 80;
server_name localhost;
location /static{
alias /home/jy/python/dailyfresh_celery任务处理者/dailyfresh/static/;
}
location / {
root /home/jy/python/dailyfresh_celery任务处理者/dailyfresh/static/;
index index.html index.htm;
}
.......省略
}
后台页面:
后端管理员,添加删除首页信息的时候,调用任务处理者,重新生成首页静态页面.
所以在 goods / admin.py
中写入如下代码:
from goods.models import GoodsType, IndexPromotionBanner
class IndexPromotionBannerAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
'''新增或者更新表中数据时调用'''
super().save_model(request, obj, form, change)
#发出任务让celery worker重新生成首页静态页面
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
def delete_model(self, request, obj):
'''删除数据时调用'''
super().delete_model(request, obj, form, change)
# 发出任务让celery worker重新生成首页静态页面
from celery_tasks.takss import generate_static_index_html
generate_static_index_html.delay()
admin.site.register(IndexPromotionBanner, IndexPromotionBannerAdmin)
测试下:
- 正常访问首页是:
127.0.0.1:8000
主机,动态生成页面(从数据库查询的信息) - nginx帮你生成的静态页面是:
127.0.0.1:80
,这个页面在celer任务处理者 static目录下 (删除,看是否 会重新生成,或者修改里面代码,测试)
测试时,访问后台管理页面,在后台添加删除一个模块,然后重新访问 上面2个页面,看是否一致.
使用缓存
将处理计算的结果先临时保存起来,下次使用的时候可以先直接使用,如果没有这个备份的数据,重新进行计算处理
将缓存数据保存在内存中 (本项目中保存在redis中)
django底层缓存API
类: django.core.cache.cache
from django.core.cache import cache
基本用法:
最基本的借口是set(key, value, timeout)
和get(key)
开头尝试从缓存中获取数据
context = cache.get('index_page_data')
如果不存在,
if context is None:
开始正常代码流程:从数据库中读取数据
结尾,把读到的数据设置到缓存里.
cache.set('index_page_data', context, 3600)
from django.core.cache import cache
class IndexView(View):
'''首页'''
def get(self, request):
'''显示首页'''
#尝试从缓存中获取数据
context = cache.get('index_page_data')
if context is None:
#缓存中没有数据:
print('设置缓存')
#获取商品的种类信息
types = GoodsType.objects.all()
for type in types:
print('*******商品分类名称:'+type.name)
#获取首页轮播商品信息
goods_banners = IndexGoodsBanner.objects.all().order_by('index')
#获取首页促销活动信息
promotion_banners = IndexPromotionBanner.objects.all().order_by('index')
#获取首页分类商品展示信息
# type_goods_banners = IndexTypeGoodsBanner.objects.all()
#获取每个种类信息
for type in types: #GoodsType
#获取type种类首页分类商品的图片的展示信息
image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')
#获取type种类首页分类商品的文字展示信息
title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
# 动态给type增加属性,分别保存首页分类商品的图片展示信息和文字展示信息
type.image_banners = image_banners
type.title_banners = title_banners
context = {'types': types,
'goods_banners': goods_banners,
'promotion_banners': promotion_banners}
#设置缓存
cache.set('index_page_data', context, 3600)
#获取用户购物车种商品数目
cart_count = 0
user = request.user
if user.is_authenticated():
#用户已经登录
conn = get_redis_connection('default')
cart_key = 'cart_%d'%user.id
cart_count = conn.hlen(cart_key)
#组织模板上下文
context.update(cart_count=cart_count)
# context = {'types':types,
# 'goods_banners':goods_banners,
# 'promotion_banners':promotion_banners,
# 'cart_count':cart_count}
return render(request, 'index.html', context)
还要修改后台管理类里,如果有增加或者删除操作,则清空缓存.(此流程类似与页面静态化.
在上述admin.py文件delete_model
和 save_model
函数中,分别加入下面清除缓存的代码.
#清楚首页缓存
cache.delete('index_page_data')