文章目录
开发环境 |
服务器端:阿里云centos7,FastDFS-v6.06,nginx-1.16.1,Redis-3.4.1,django-redis-4.11.1
本地端:win7-64位,Django2.2,python3.7,pycharm2018.3,Redis-3.3.11,Django-Redis-4.11
一. 首页商品获取与展示
1. index模板继承改造
{% 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 %}
2. 商品模型类回顾
3. 首页内容获取
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: # 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}
# 设置缓存
# key value timeout
cache.set('index_page_data', context, 3600)
# 组织模板上下文
context.update(cart_count=cart_count)
# 使用模板
return render(request, 'index.html', context)
4. Redis存储购物车记录
Redis官方文档参考:https://www.redis.net.cn/tutorial/3509.html
获取哈希表中字段的数量:https://www.redis.net.cn/order/3571.html
# 获取用户购物车中商品的数目
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)
在Redis中按上述格式添加一条浏览记录测试:
二. 静态首页与缓存
1. celery生成静态首页
把原本动态的页面处理结果保存成html文件,让用户直接访问这个生成出来的静态的html页面
@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: # 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.模板渲染
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)
将Django文件复制一份到服务器中,在服务器里启动task
在本地端测试使用celery生成静态首页:
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
查看服务器端:
再查看static目录下是否有index文件生成:
2. 配置Nginx提交静态页面
重新启动Nginx:
class BaseModelAdmin(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()
# 清除首页的缓存数据
cache.delete('index_page_data')
def delete_model(self, request, obj):
'''删除表中的数据时调用'''
super().delete_model(request, obj)
# 发出任务,让celery worker重新生成首页静态页
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
# 清除首页的缓存数据
cache.delete('index_page_data')
在本地端打开admin管理页面,调整首页商品展示顺序,打开服务端的celery和Nginx测试下:
调整成功
3. 调度(后面才涉及)
核心知识点 |
在数据库中取出数据,生成首页HTML模板
使用celery生成静态页面
配置Nginx提供静态页面
管理员修改首页所使用表中的数据时,重新生成index静态页面