Django--dailyfresh--首页(4)

首页

使用父模板重构首页页面

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')
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值