Django电商项目(五)页面静态化、设置缓存、首页内容获取展示、历史记录

网页优化-首页页面静态化

首页访问次数多 不经常更改可以进行页面静态化

把原本动态的页面处理结果保存成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:  # 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)

新建模板文件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
# Register your models here.


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')


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


# http://127.0.0.1:8000
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)

        # 获取用户购物车中商品的数目
        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


# http://127.0.0.1:8000
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)

        # 获取用户购物车中商品的数目
        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

# /goods/商品id
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]

        # 获取同一个SPU的其他规格商品
        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
            # 移除列表中的goods_id
            conn.lrem(history_key, 0, goods_id)
            # 把goods_id插入到列表的左侧
            conn.lpush(history_key, goods_id)
            # 只保存用户最新浏览的5条信息
            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)

猜你喜欢

转载自blog.csdn.net/qq_27251475/article/details/120679856