首页
使用父模板重构首页页面
templates/index.html
使用父模板重构首页页面
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}天天生鲜-首页{% endblock title %}
{% block topfile %}
<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 topfile %}
{% 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="#model01" class="fruit">新鲜水果</a></li> -->
<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><img src="images/slide.jpg" alt="幻灯片"></li> -->
<li><a href="#"> <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="#"><img src="images/adv01.jpg"></a>-->
<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="model01">新鲜水果</h3> -->
<h3 class="fl" id="model0{{ forloop.counter }}">{{type.name}}</h3>
<div class="subtitle fl">
<span>|</span>
{% for banner in type.title_banners %}
<!--<a href="#">鲜芒</a> -->
<a href="#">{{ 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="images/banner01.jpg"></div> -->
<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="#">草莓</a></h4>-->
<h4><a href="#">{{ banner.sku.name }}</a></h4>
<!--<a href="#"><img src="images/goods/goods003.jpg"></a>-->
<a href="#"><img src="{{ banner.sku.image.url }}"></a>
<!--<div class="prize">¥ 30.00</div>-->
<div class="prize">{{ banner.sku.price }}</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endfor %}
{% endblock body %}
goods/urls.py
from django.conf.urls import url
from goods.views import IndexView
urlpatterns = [
url(r'^$',IndexView.as_view(),name='index') #首页
]
goods/views.py
from django.shortcuts import render
from django.views.generic import View
# Create your views here.
#http://127.0.0.1:8000
class IndexView(View):
'''首页'''
def get(self,request):
'''显示首页'''
return render(request,'index.html')
重写代码获取数据
from django.shortcuts import render
from django.views.generic import View
from goods.models import GoodsType,IndexGoodsBanner,IndexPromotionBanner,IndexTypeGoodsBanner
# Create your views here.
#http://127.0.0.1:8000
class IndexView(View):
'''首页'''
def get(self,request):
'''显示首页'''
# 获取商品的种类信息
types = GoodsType.objects.all()
# 获取首页轮播商品信息
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:
# 获取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
# 获取用户购物车商品的数目
cart_count = 0
# 组织模板上下文
context = {'types':types,
'goods_banners':goods_banners,
'promotion_banners':promotion_banners,
'cart_count':cart_count,
}
return render(request,'index.html',context)
购物车记录
当用户点击加入购物车时需要添加购物车记录
使用 Redis
存储购物车记录
存储购物车的格式: 一个用户的购物车数据用一条记录保存
记录关键:对应商品(SKU)ID 和 购物数量
'cart_1':('1':3,'2':5,..)
哈希
用户1的购物车,商品为1的3件,商品为2的5件
goods/view.py
class IndexView(View):
'''首页'''
def get(self,request):
# 获取用户购物车商品的数目
# 判断 用户是否登陆
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)
首页页面的静态化
当管理员修改了信息,需要重新生成首页静态页面
使用celery
完成
celery_tasks/tasks.py
新增
# 使用celery
from celery import Celery #导入 Celery 类
from django.conf import settings # 导入dailyfresh/settings.py 中配置信息
from django.core.mail import send_mail #导入 发送邮件函数
from django.template import loader,RequestContext
import os
import time
# Django 配置初始化,以便celery的监听工作者 可以使用 Django中的一些信息
# 在任务处理者一段,添加如下代码
#import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfresh.settings") #源码在 dailyfresh/wsgi.py 中
django.setup()
from goods.models import GoodsType,IndexGoodsBanner,IndexPromotionBanner,IndexTypeGoodsBanner
#创建一个Celery 对象
app = Celery('celery_tasks.tasks',broker='redis://127.0.0.1:6379/8')
#第一个参数是路径, broker 定义队列
@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')
# 获取首页分类商品展示信息
#type_goods_banners = IndexTypeGoodsBanner.objects.all()
for type in types:
# 获取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)
#3. 模板渲染,
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)
templates/static_base.html
基于 base 父模板,用于首页静态化
测试生成
python manage.py shell
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
配置 nginx 访问刚才生成的静态页面
用户访问 Nginx 就能访问静态化页面
cd /usr/local/nginx/conf
su root
vim nginx.conf
添加如下
server {
listen 80;
server_name localhost;
location /static {
alias /home/mikowoo/Documents/dailyfresh_send_email/dailyfresh/static/;
}
location / {
root /home/mikowoo/Documents/dailyfresh_send_email/dailyfresh/static/;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
重启动 Nginx 服务
/usr/local/nginx/sbin/nginx -s reload
测试
http://127.0.0.1/
默认80 端口
或者直接访问IP地址 192.168.50.91
管理员更新首页内,重新生成index静态化页面
goods/admin.py
from django.contrib import admin
from goods.models import GoodsType,GoodsSKU,Goods,IndexGoodsBanner,IndexPromotionBanner,IndexTypeGoodsBanner
# Register your models here.
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)
# 发出任务,使celery worker 重新生成首页静态页面
from celery_tasks.tasks import generate_static_index_html
generate_static_index_html.delay()
admin.site.register(GoodsType)
admin.site.register(GoodsSKU)
admin.site.register(Goods)
admin.site.register(IndexGoodsBanner)
admin.site.register(IndexPromotionBanner,IndexPromotionBannerAdmin)
admin.site.register(IndexTypeGoodsBanner)
优化
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()
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()
class GoodsTypeAdmin(BaseModelAdmin):
pass
class GoodsSKUAdmin(BaseModelAdmin):
pass
class GoodsAdmin(BaseModelAdmin):
pass
class IndexGoodsBannerAdmin(BaseModelAdmin):
pass
class IndexPromotionBannerAdmin(BaseModelAdmin):
pass
class IndexTypeGoodsBannerAdmin(BaseModelAdmin):
pass
admin.site.register(GoodsType,GoodsTypeAdmin)
admin.site.register(GoodsSKU,GoodsSKUAdmin)
admin.site.register(Goods,GoodsAdmin)
admin.site.register(IndexGoodsBanner,IndexGoodsBannerAdmin)
admin.site.register(IndexPromotionBanner,IndexPromotionBannerAdmin)
admin.site.register(IndexTypeGoodsBanner,IndexTypeGoodsBannerAdmin)
访问首页时,使用调度服务器区分到底是访问Django服务器中的视图,还是 Celery 服务器中的静态首页
调度服务器 :由 Nginx 搭建
比如:
192.168.50.91
访问 Cerlery 服务器中的静态首页
192.168.50.91/index
访问 Django 中的视图
goods/urls.py
修改
urlpatterns = [
url(r'^index$',IndexView.as_view(),name='index') #首页
]
页面数据缓存
减少数据库查询次数
goods/views.py
修改
设置缓存
from django.core.cache import cache
# Create your views here.
#http://127.0.0.1:8000
class IndexView(View):
'''首页'''
def get(self,request):
'''显示首页'''
# 尝试从缓存中获取数据
context = cache.get('index_page_data') # 无数据,返回 None
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')
# 获取首页分类商品展示信息
#type_goods_banners = IndexTypeGoodsBanner.objects.all()
for type in types:
# 获取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)
# cache.set(key,value,timeout)第一个参数为缓存名称,第三个参数为过期时间,可选的,默认永久缓存
...
...
# 组织模板上下文
context.update(cart_count = cart_count)
return render(request,'index.html',context)
查看缓存数据
更新缓存:后台管理员更新数据后
goods/admins.py
from django.contrib import admin
from django.core.cache import cache
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')