网页优化-首页页面静态化
首页访问次数多 不经常更改可以进行页面静态化
把原本动态的页面处理结果保存成html文件,让用户直接访问这个生成出来的静态的html页面
在celery_tasks.tasks.py再定义一个任务函数 使用首页的view函数进行修改
from django.template import loader, RequestContext
from goods.models import GoodsType,IndexGoodsBanner,IndexPromotionBanner,IndexTypeGoodsBanner
from django_redis import get_redis_connection
@app.task
def generate_static_index_html():
'''产生首页静态页面'''
types = GoodsType.objects.all()
goods_banners = IndexGoodsBanner.objects.all().order_by('index')
promotion_banners = IndexPromotionBanner.objects.all().order_by('index')
for type in types:
image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')
title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
type.image_banners = image_banners
type.title_banners = title_banners
context = {'types': types,
'goods_banners': goods_banners,
'promotion_banners': promotion_banners}
temp = loader.get_template('static_index.html')
static_index_html = temp.render(context)
save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
with open(save_path, 'w') as f:
f.write(static_index_html)
新建模板文件static_base.html去除登录后相关内容 并新建static_index.html使其继承static_base.html 内容与index文件一样 仍需将项目文件放置在celery所在服务器中并进行重新启动celery celery -A celery_tasks.tasks worker -l info
在djanggo执行 可以在celery所在服务器生成静态文件
配置nginx提交静态页面
sudo vi ./conf/nginx.conf 新添加一个server端口不与之前的重复 添加保存后重启nginx即可
admin管理更新首页数据表数据时重新生成index静态页面
参考文档https://doc.codingdict.com/django/ref/contrib/admin/index.html#modeladmin-methods goods/admin.py
from django.contrib import admin
from django.core.cache import cache
from goods.models import GoodsType,IndexPromotionBanner,IndexGoodsBanner,IndexTypeGoodsBanner
class BaseModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
'''新增或更新表中的数据时调用'''
super().save_model(request, obj, form, change)
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
cache.delete('index_page_data')
def delete_model(self, request, obj):
'''删除表中的数据时调用'''
super().delete_model(request, obj)
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
cache.delete('index_page_data')
class GoodsTypeAdmin(BaseModelAdmin):
pass
class IndexGoodsBannerAdmin(BaseModelAdmin):
pass
class IndexTypeGoodsBannerAdmin(BaseModelAdmin):
pass
class IndexPromotionBannerAdmin(BaseModelAdmin):
pass
admin.site.register(GoodsType, GoodsTypeAdmin)
admin.site.register(IndexGoodsBanner, IndexGoodsBannerAdmin)
admin.site.register(IndexTypeGoodsBanner, IndexTypeGoodsBannerAdmin)
admin.site.register(IndexPromotionBanner, IndexPromotionBannerAdmin)
修改或删除会重新生成静态页面 修改首页url为/index
网页优化-页面缓存
将处理计算的结果先临时保存起来,下次使用的时候可以先直接使用,如果没有这个备份的数据,重新进行计算处理
将缓存数据保存在内存中 (本项目中保存在redis中,获取速度快) cache 修改了数据库的数据,直接删除缓存 缓存要设置有效期
django文档: https://doc.codingdict.com/django/topics/cache.html 站点级别缓存,将整个网站进行缓存,占用空间大 单个view缓存,页面在不同时间可能会有区别 不太合适 模板片段缓存,最后使用模板 不太合适 使用底层API缓存
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()
goods_banners = IndexGoodsBanner.objects.all().order_by('index')
promotion_banners = IndexPromotionBanner.objects.all().order_by('index')
for type in types:
image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')
title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
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)
user = request.user
cart_count = 0
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)
return render(request, 'index.html', context)
更新缓存
网页优化的优点 DDOS:黑客控制大批量肉鸡访问网站
首页内容获取和展示
购物车参数显示
修改模板文件
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}天天生鲜-首页{% endblock title %}
{% block topfiles %}
<script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/jquery-ui.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/slide.js' %}"></script>
{% endblock topfiles %}
{% block body %}
<div class="navbar_con">
<div class="navbar">
<h1 class="fl">全部商品分类</h1>
<ul class="navlist fl">
<li><a href="">首页</a></li>
<li class="interval">|</li>
<li><a href="">手机生鲜</a></li>
<li class="interval">|</li>
<li><a href="">抽奖</a></li>
</ul>
</div>
</div>
<div class="center_con clearfix">
<ul class="subnav fl">
{% for type in types %}
<li><a href="#model0{{ forloop.counter }}" class="{{ type.logo }}">{{ type.name }}</a></li>
{% endfor %}
</ul>
<div class="slide fl">
<ul class="slide_pics">
{% for banner in goods_banners %}
<li><a href="{% url 'goods:detail' banner.sku.id %}"><img src="{{ banner.image.url }}" alt="幻灯片"></a></li>
{% endfor %}
</ul>
<div class="prev"></div>
<div class="next"></div>
<ul class="points"></ul>
</div>
<div class="adv fl">
{% for banner in promotion_banners %}
<a href="{{ banner.url }}"><img src="{{ banner.image.url }}"></a>
{% endfor %}
</div>
</div>
{% for type in types %}
<div class="list_model">
<div class="list_title clearfix">
<h3 class="fl" id="model0{{ forloop.counter }}">{{ type.name }}</h3>
<div class="subtitle fl">
<span>|</span>
{% for banner in type.title_banners %}
<a href="{% url 'goods:detail' banner.sku.id %}">{{ banner.sku.name }}</a>
{% endfor %}
</div>
<a href="#" class="goods_more fr" id="fruit_more">查看更多 ></a>
</div>
<div class="goods_con clearfix">
<div class="goods_banner fl"><img src="{{ type.image.url }}"></div>
<ul class="goods_list fl">
{% for banner in type.image_banners %}
<li>
<h4><a href="{% url 'goods:detail' banner.sku.id %}">{{ banner.sku.name }}</a></h4>
<a href="{% url 'goods:detail' banner.sku.id %}"><img src="{{ banner.sku.image.url }}"></a>
<div class="prize">¥ {{ banner.sku.price }}</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
{% endblock body %}
创建视图函数 goods/view.py
class IndexView(View):
'''首页'''
def get(self, request):
'''显示首页'''
context = cache.get('index_page_data')
if context is None:
print('设置缓存')
types = GoodsType.objects.all()
goods_banners = IndexGoodsBanner.objects.all().order_by('index')
promotion_banners = IndexPromotionBanner.objects.all().order_by('index')
for type in types:
image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')
title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
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)
user = request.user
cart_count = 0
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)
return render(request, 'index.html', context)
商品历史记录
参考命令:redisdoc.com 修改模板文件
{% extends 'base_user_center.html' %}
{% block right_content %}
<div class="right_content clearfix">
<div class="info_con clearfix">
<h3 class="common_title2">基本信息</h3>
<ul class="user_info_list">
<li><span>用户名:</span>{{ user.username }}</li>
{% if address %}
<li><span>联系方式:</span>{{ address.phone }}</li>
<li><span>联系地址:</span>{{ address.addr }}</li>
{% else %}
<li><span>联系方式:</span>无默认</li>
<li><span>联系地址:</span>无默认</li>
{% endif %}
</ul>
</div>
<h3 class="common_title2">最近浏览</h3>
<div class="has_view_list">
<ul class="goods_type_list clearfix">
{% for goods in goods_li %}
<li>
<a href="{% url 'goods:detail' goods.id %}"><img src="{{ goods.image.url }}"></a>
<h4><a href="{% url 'goods:detail' goods.id %}">{{ goods.name }}</a></h4>
<div class="operate">
<span class="prize">¥{{ goods.price }}</span>
<span class="unit">{{ goods.price }}/{{ goods.unite }}</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
{% empty %}
无历史浏览记录
{% endfor %}
</ul>
</div>
</div>
{% endblock right_content %}
view.py
class DetailView(View):
'''详情页'''
def get(self, request, goods_id):
'''显示详情页'''
try:
sku = GoodsSKU.objects.get(id=goods_id)
except GoodsSKU.DoesNotExist:
return redirect(reverse('goods:index'))
types = GoodsType.objects.all()
sku_orders = OrderGoods.objects.filter(sku=sku).exclude(comment='')
new_skus = GoodsSKU.objects.filter(type=sku.type).order_by('-create_time')[:2]
same_spu_skus = GoodsSKU.objects.filter(goods=sku.goods).exclude(id=goods_id)
user = request.user
cart_count = 0
if user.is_authenticated():
conn = get_redis_connection('default')
cart_key = 'cart_%d' % user.id
cart_count = conn.hlen(cart_key)
conn = get_redis_connection('default')
history_key = 'history_%d'%user.id
conn.lrem(history_key, 0, goods_id)
conn.lpush(history_key, goods_id)
conn.ltrim(history_key, 0, 4)
context = {'sku':sku, 'types':types,
'sku_orders':sku_orders,
'new_skus':new_skus,
'same_spu_skus':same_spu_skus,
'cart_count':cart_count}
return render(request, 'detail.html', context)
|