DJANGO-天天生鲜项目从0到1-007-首页静态化与缓存

本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习

https://www.bilibili.com/video/BV1vt41147K8?p=1

页面静态化

为什么需要静态化首页

主页是一个网站被访问次数最多的页面,且不管用户登不登陆都可以访问,每次访问主页时,都需要从数据库中查询数据,而且每次访问几乎展示的内容都是一样的,除非后台管理员修改了主页的数据信息。

所以可以将主页单独做出来一个静态的页面(其中包括了数据信息),让未登录的用户直接访问该页面,这样就能够减少服务器的压力。

又因为该页面是静态写死的,如果后台数据变化了,这个页面的信息也还是原来的信息,为了解决这个问题,保持静态页面的数据是最新的,可以在后台管理员每次修改了首页数据信息时,重新生成新的静态页面。

如何生成静态化页面

当管理员每次更新首页需要的数据时,就可以调用生成静态化页面的方法,而这时,如果生成静态化页面处理时间比较长,那么可能会造成管理员前台长时间的等待,因此可以通过celery来进行异步的生成页面。

celery的配置与‘DJANGO-天天生鲜项目从0到1-002-用户模块-注册’中的利用celery一样,因此在其基础上的tasks.py文件上新增一个任务即可。

获取首页数据

因为获取首页的数据在多个地方都需要使用到,因此将其封装成一个方法,与上一节的获取购物车数量一样,放在utils/utils.py中:

from goods.models import *

def
get_index_data(): '''获取首页数据信息''' # 获取商品分类 goods_type = GoodsType.objects.all() # 获取轮播商品 goods_banner = IndexGoodsBanner.objects.all().order_by('index') # 获取活动信息 promotion_banner = IndexPromotionBanner.objects.all().order_by('index') # 获取分类商品展示信息 for goodstype in goods_type: # 获取该类型下面的商品的标题信息,并进行排序 title_banner = IndexTypeGoodsBanner.objects.filter(goodstype=goodstype, display_type=0).order_by('index') # 获取该类型下面的商品的图片信息,并进行排序 image_banner = IndexTypeGoodsBanner.objects.filter(goodstype=goodstype, display_type=1).order_by('index') # 动态给type增加属性,分别保存首页分类商品的文字信息和图片信息 goodstype.title_banner = title_banner goodstype.image_banner = image_banner # 组织上下文 context = { 'goods_type': goods_type, 'goods_banner': goods_banner, 'promotion_banner': promotion_banner, } return context

创建celery任务

获取数据后,仍然使用goods/index.html模板文件,使用模板对象的render方法将获取到的数据填入模板文件中生成html内容,再通过with open将html内容写入至static下的index.html文件中,这里需要先创建出该空文件。

from utils.utils import get_index_data
from django.template import loader

@app.task()
def generate_static_index():
    # 获取需要展示的信息
    context = get_index_data()
    # 使用模板
    # 加载模板文件,返回模板对象
    template = loader.get_template('goods/index.html')
    # 渲染模板
    static_index = template.render(context)

    # 生成html文件
    save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
    with open(save_path, 'w') as f:
        f.write(static_index)

创建admin模型管理类,调用celery任务

我们需要后台管理员在修改了首页数据信息时调用创建静态文件的celery任务,因此需要用到admin模型管理类,重写相关模型类的save和delete方法

编辑goods/admin.py文件:

from django.contrib import admin
from goods.models import *
from utils.tasks import generate_static_index
from django.core.cache import cache
# Register your models here.

class BaseModelAdmin(admin.ModelAdmin):
    '''模型管理站点'''
    def save_model(self, request, obj, form, change):
        # 继承父类方法
        super().save_model(request, obj, form, change)
        # 调用celery重新生成静态首页文件
        generate_static_index.delay()
        # 清除缓存
        cache.delete('index_data')

    def delete_model(self, request, obj):
        # 继承父类方法
        super().delete_model(request, obj)
        # 调用celery重新生成静态首页文件
        generate_static_index.delay()
        # 清除缓存
        cache.delete('index_data')

admin.site.register(Goods, BaseModelAdmin)
admin.site.register(GoodsSPU, BaseModelAdmin)
admin.site.register(GoodsType, BaseModelAdmin)
admin.site.register(GoodsImage, BaseModelAdmin)
admin.site.register(IndexGoodsBanner, BaseModelAdmin)
admin.site.register(IndexTypeGoodsBanner, BaseModelAdmin)
admin.site.register(IndexPromotionBanner, BaseModelAdmin)

通过Nginx访问静态页面

上面生成的静态页面只能够通过django服务器ip:8000/static/index.html网址访问,但是我们想要的是用户直接输入ip地址后就能访问静态页面,于是需要Nginx帮忙。在Nginx配置文件(/usr/local/nginx/conf/nginx.conf)中,修改如下配置:

server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location /static {
            alias /home/gong/study/projects/dailyfresh/static/;
        }
        location / {
            #root   html;
            root /home/gong/study/projects/dailyfresh/static/;
            index index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

在浏览器中输入IP地址后不输入端口号时,则默认访问的是80端口,location相当于是url匹配器,从上往下进行匹配,若符合ip/static,则显示 /home/gong/study/projects/dailyfresh/static/ 下面的index.html文件,若ip地址后面什么都没有输入,则也显示/home/gong/study/projects/dailyfresh/static/下面的index%文件

在浏览器中输入http://192.168.183.129/static/http://192.168.183.129时访问的就是生成的静态页面

何时访问静态化首页,何时访问正常动态化的首页

当我们访问静态化首页时,访问的地址是http://192.168.183.129,默认的是80端口,访问到的服务器是Nginx服务器

当我们访问动态化首页时,访问的地址是http://192.168.183.129:8000,是8000端口,访问到的是服务器是Django服务器

但是部署上线后,最后暴露给用户的地址肯定只有一个,而不是将上述两个地址给用户,让用户选择访问哪个页面,这里就需要在用户和(Nginx、Django)服务器之间,再搭一台Nginx服务器,通过这台Nginx服务器给用户暴露一个浏览的地址(比如为http://192.168.183.130),然后让服务器判断决定用户最终访问的服务器是哪个(比如当用户直接输入http://192.168.183.130时,中间的Nginx最终让其访问的是Nginx指向的静态首页,当用户输入http://192.168.183.130/index时,中间的Nginx最终让其访问的是Django服务器的动态首页)。

缓存首页数据信息

当我们不是访问静态页面的首页,而是访问正常动态首页时,每次访问也依然需要重新查询数据库,而其实查出来的数据基本都是一样的,除非后台管理员修改了后台数据,这时为了避免重复查询,可以使用django的缓存机制,将第一次查出来的数据放入django服务器的缓存中(注意不是浏览器的缓存),后续访问页面时,先在缓存中查询数据是否存在,存在即直接取出数据,不存在即重新查询数据。

配置django缓存

缓存可以存在数据库或者文件系统中,一般我们都会存在内存型数据库汇总,前面登录配置session时(DJANGO-天天生鲜项目从0到1-003-用户模块-登录),已经配好了将缓存存在redis数据库中

CACHES = {
  "default": {
    "BACKEND": "django_redis.cache.RedisCache",
    "LOCATION": "redis://127.0.0.1:6379/1",
    "OPTIONS": {
      "CLIENT_CLASS": "django_redis.client.DefaultClient",
    }
  }
}

使用django缓存,cache.get(key),cache.set(key, data, timeout)

在首页view.py中,在查询数据库信息前,先通过cache.get从缓存中查询是否存在需要的数据,若不存在则在查询完一些公用的数据库信息之后,将这些公用信息通过cache.set存在缓存中

from django.core.cache import cache

class IndexView(View):
    '''首页视图'''
    template_name = 'goods/index.html'
    def get(self, request):
        '''显示首页'''
        # 从缓存汇总获取数据
        context = cache.get('index_data')
        if not context:
            # 获取数据库信息
            context = get_index_data()
            # 设置缓存,3600秒过期
            print('设置缓存')
            cache.set('index_data', context, 3600)

        # 获取购物车数量,购物车存储格式为:cart_userid : {'goodsid': quantity}
        cart_count = get_cart_count(request)
        context['cart_count'] = cart_count
        return render(request, self.template_name, context)

删除缓存,cache.delete(key)

同样在后台管理员修改了首页数据库信息时,需要将原来的缓存删除掉,等删除后再次访问首页时,重新设置新的缓存信息

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

https://www.bilibili.com/video/BV1vt41147K8?p=1

页面静态化

为什么需要静态化首页

主页是一个网站被访问次数最多的页面,且不管用户登不登陆都可以访问,每次访问主页时,都需要从数据库中查询数据,而且每次访问几乎展示的内容都是一样的,除非后台管理员修改了主页的数据信息。

所以可以将主页单独做出来一个静态的页面(其中包括了数据信息),让未登录的用户直接访问该页面,这样就能够减少服务器的压力。

又因为该页面是静态写死的,如果后台数据变化了,这个页面的信息也还是原来的信息,为了解决这个问题,保持静态页面的数据是最新的,可以在后台管理员每次修改了首页数据信息时,重新生成新的静态页面。

如何生成静态化页面

当管理员每次更新首页需要的数据时,就可以调用生成静态化页面的方法,而这时,如果生成静态化页面处理时间比较长,那么可能会造成管理员前台长时间的等待,因此可以通过celery来进行异步的生成页面。

celery的配置与‘DJANGO-天天生鲜项目从0到1-002-用户模块-注册’中的利用celery一样,因此在其基础上的tasks.py文件上新增一个任务即可。

获取首页数据

因为获取首页的数据在多个地方都需要使用到,因此将其封装成一个方法,与上一节的获取购物车数量一样,放在utils/utils.py中:

from goods.models import *

def
get_index_data(): '''获取首页数据信息''' # 获取商品分类 goods_type = GoodsType.objects.all() # 获取轮播商品 goods_banner = IndexGoodsBanner.objects.all().order_by('index') # 获取活动信息 promotion_banner = IndexPromotionBanner.objects.all().order_by('index') # 获取分类商品展示信息 for goodstype in goods_type: # 获取该类型下面的商品的标题信息,并进行排序 title_banner = IndexTypeGoodsBanner.objects.filter(goodstype=goodstype, display_type=0).order_by('index') # 获取该类型下面的商品的图片信息,并进行排序 image_banner = IndexTypeGoodsBanner.objects.filter(goodstype=goodstype, display_type=1).order_by('index') # 动态给type增加属性,分别保存首页分类商品的文字信息和图片信息 goodstype.title_banner = title_banner goodstype.image_banner = image_banner # 组织上下文 context = { 'goods_type': goods_type, 'goods_banner': goods_banner, 'promotion_banner': promotion_banner, } return context

创建celery任务

获取数据后,仍然使用goods/index.html模板文件,使用模板对象的render方法将获取到的数据填入模板文件中生成html内容,再通过with open将html内容写入至static下的index.html文件中,这里需要先创建出该空文件。

from utils.utils import get_index_data
from django.template import loader

@app.task()
def generate_static_index():
    # 获取需要展示的信息
    context = get_index_data()
    # 使用模板
    # 加载模板文件,返回模板对象
    template = loader.get_template('goods/index.html')
    # 渲染模板
    static_index = template.render(context)

    # 生成html文件
    save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
    with open(save_path, 'w') as f:
        f.write(static_index)

创建admin模型管理类,调用celery任务

我们需要后台管理员在修改了首页数据信息时调用创建静态文件的celery任务,因此需要用到admin模型管理类,重写相关模型类的save和delete方法

编辑goods/admin.py文件:

from django.contrib import admin
from goods.models import *
from utils.tasks import generate_static_index
from django.core.cache import cache
# Register your models here.

class BaseModelAdmin(admin.ModelAdmin):
    '''模型管理站点'''
    def save_model(self, request, obj, form, change):
        # 继承父类方法
        super().save_model(request, obj, form, change)
        # 调用celery重新生成静态首页文件
        generate_static_index.delay()
        # 清除缓存
        cache.delete('index_data')

    def delete_model(self, request, obj):
        # 继承父类方法
        super().delete_model(request, obj)
        # 调用celery重新生成静态首页文件
        generate_static_index.delay()
        # 清除缓存
        cache.delete('index_data')

admin.site.register(Goods, BaseModelAdmin)
admin.site.register(GoodsSPU, BaseModelAdmin)
admin.site.register(GoodsType, BaseModelAdmin)
admin.site.register(GoodsImage, BaseModelAdmin)
admin.site.register(IndexGoodsBanner, BaseModelAdmin)
admin.site.register(IndexTypeGoodsBanner, BaseModelAdmin)
admin.site.register(IndexPromotionBanner, BaseModelAdmin)

通过Nginx访问静态页面

上面生成的静态页面只能够通过django服务器ip:8000/static/index.html网址访问,但是我们想要的是用户直接输入ip地址后就能访问静态页面,于是需要Nginx帮忙。在Nginx配置文件(/usr/local/nginx/conf/nginx.conf)中,修改如下配置:

server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location /static {
            alias /home/gong/study/projects/dailyfresh/static/;
        }
        location / {
            #root   html;
            root /home/gong/study/projects/dailyfresh/static/;
            index index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

在浏览器中输入IP地址后不输入端口号时,则默认访问的是80端口,location相当于是url匹配器,从上往下进行匹配,若符合ip/static,则显示 /home/gong/study/projects/dailyfresh/static/ 下面的index.html文件,若ip地址后面什么都没有输入,则也显示/home/gong/study/projects/dailyfresh/static/下面的index%文件

在浏览器中输入http://192.168.183.129/static/http://192.168.183.129时访问的就是生成的静态页面

何时访问静态化首页,何时访问正常动态化的首页

当我们访问静态化首页时,访问的地址是http://192.168.183.129,默认的是80端口,访问到的服务器是Nginx服务器

当我们访问动态化首页时,访问的地址是http://192.168.183.129:8000,是8000端口,访问到的是服务器是Django服务器

但是部署上线后,最后暴露给用户的地址肯定只有一个,而不是将上述两个地址给用户,让用户选择访问哪个页面,这里就需要在用户和(Nginx、Django)服务器之间,再搭一台Nginx服务器,通过这台Nginx服务器给用户暴露一个浏览的地址(比如为http://192.168.183.130),然后让服务器判断决定用户最终访问的服务器是哪个(比如当用户直接输入http://192.168.183.130时,中间的Nginx最终让其访问的是Nginx指向的静态首页,当用户输入http://192.168.183.130/index时,中间的Nginx最终让其访问的是Django服务器的动态首页)。

缓存首页数据信息

当我们不是访问静态页面的首页,而是访问正常动态首页时,每次访问也依然需要重新查询数据库,而其实查出来的数据基本都是一样的,除非后台管理员修改了后台数据,这时为了避免重复查询,可以使用django的缓存机制,将第一次查出来的数据放入django服务器的缓存中(注意不是浏览器的缓存),后续访问页面时,先在缓存中查询数据是否存在,存在即直接取出数据,不存在即重新查询数据。

配置django缓存

缓存可以存在数据库或者文件系统中,一般我们都会存在内存型数据库汇总,前面登录配置session时(DJANGO-天天生鲜项目从0到1-003-用户模块-登录),已经配好了将缓存存在redis数据库中

CACHES = {
  "default": {
    "BACKEND": "django_redis.cache.RedisCache",
    "LOCATION": "redis://127.0.0.1:6379/1",
    "OPTIONS": {
      "CLIENT_CLASS": "django_redis.client.DefaultClient",
    }
  }
}

使用django缓存,cache.get(key),cache.set(key, data, timeout)

在首页view.py中,在查询数据库信息前,先通过cache.get从缓存中查询是否存在需要的数据,若不存在则在查询完一些公用的数据库信息之后,将这些公用信息通过cache.set存在缓存中

from django.core.cache import cache

class IndexView(View):
    '''首页视图'''
    template_name = 'goods/index.html'
    def get(self, request):
        '''显示首页'''
        # 从缓存汇总获取数据
        context = cache.get('index_data')
        if not context:
            # 获取数据库信息
            context = get_index_data()
            # 设置缓存,3600秒过期
            print('设置缓存')
            cache.set('index_data', context, 3600)

        # 获取购物车数量,购物车存储格式为:cart_userid : {'goodsid': quantity}
        cart_count = get_cart_count(request)
        context['cart_count'] = cart_count
        return render(request, self.template_name, context)

删除缓存,cache.delete(key)

同样在后台管理员修改了首页数据库信息时,需要将原来的缓存删除掉,等删除后再次访问首页时,重新设置新的缓存信息

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

https://www.bilibili.com/video/BV1vt41147K8?p=1

页面静态化

为什么需要静态化首页

主页是一个网站被访问次数最多的页面,且不管用户登不登陆都可以访问,每次访问主页时,都需要从数据库中查询数据,而且每次访问几乎展示的内容都是一样的,除非后台管理员修改了主页的数据信息。

所以可以将主页单独做出来一个静态的页面(其中包括了数据信息),让未登录的用户直接访问该页面,这样就能够减少服务器的压力。

又因为该页面是静态写死的,如果后台数据变化了,这个页面的信息也还是原来的信息,为了解决这个问题,保持静态页面的数据是最新的,可以在后台管理员每次修改了首页数据信息时,重新生成新的静态页面。

如何生成静态化页面

当管理员每次更新首页需要的数据时,就可以调用生成静态化页面的方法,而这时,如果生成静态化页面处理时间比较长,那么可能会造成管理员前台长时间的等待,因此可以通过celery来进行异步的生成页面。

celery的配置与‘DJANGO-天天生鲜项目从0到1-002-用户模块-注册’中的利用celery一样,因此在其基础上的tasks.py文件上新增一个任务即可。

获取首页数据

因为获取首页的数据在多个地方都需要使用到,因此将其封装成一个方法,与上一节的获取购物车数量一样,放在utils/utils.py中:

from goods.models import *

def
get_index_data(): '''获取首页数据信息''' # 获取商品分类 goods_type = GoodsType.objects.all() # 获取轮播商品 goods_banner = IndexGoodsBanner.objects.all().order_by('index') # 获取活动信息 promotion_banner = IndexPromotionBanner.objects.all().order_by('index') # 获取分类商品展示信息 for goodstype in goods_type: # 获取该类型下面的商品的标题信息,并进行排序 title_banner = IndexTypeGoodsBanner.objects.filter(goodstype=goodstype, display_type=0).order_by('index') # 获取该类型下面的商品的图片信息,并进行排序 image_banner = IndexTypeGoodsBanner.objects.filter(goodstype=goodstype, display_type=1).order_by('index') # 动态给type增加属性,分别保存首页分类商品的文字信息和图片信息 goodstype.title_banner = title_banner goodstype.image_banner = image_banner # 组织上下文 context = { 'goods_type': goods_type, 'goods_banner': goods_banner, 'promotion_banner': promotion_banner, } return context

创建celery任务

获取数据后,仍然使用goods/index.html模板文件,使用模板对象的render方法将获取到的数据填入模板文件中生成html内容,再通过with open将html内容写入至static下的index.html文件中,这里需要先创建出该空文件。

from utils.utils import get_index_data
from django.template import loader

@app.task()
def generate_static_index():
    # 获取需要展示的信息
    context = get_index_data()
    # 使用模板
    # 加载模板文件,返回模板对象
    template = loader.get_template('goods/index.html')
    # 渲染模板
    static_index = template.render(context)

    # 生成html文件
    save_path = os.path.join(settings.BASE_DIR, 'static/index.html')
    with open(save_path, 'w') as f:
        f.write(static_index)

创建admin模型管理类,调用celery任务

我们需要后台管理员在修改了首页数据信息时调用创建静态文件的celery任务,因此需要用到admin模型管理类,重写相关模型类的save和delete方法

编辑goods/admin.py文件:

from django.contrib import admin
from goods.models import *
from utils.tasks import generate_static_index
from django.core.cache import cache
# Register your models here.

class BaseModelAdmin(admin.ModelAdmin):
    '''模型管理站点'''
    def save_model(self, request, obj, form, change):
        # 继承父类方法
        super().save_model(request, obj, form, change)
        # 调用celery重新生成静态首页文件
        generate_static_index.delay()
        # 清除缓存
        cache.delete('index_data')

    def delete_model(self, request, obj):
        # 继承父类方法
        super().delete_model(request, obj)
        # 调用celery重新生成静态首页文件
        generate_static_index.delay()
        # 清除缓存
        cache.delete('index_data')

admin.site.register(Goods, BaseModelAdmin)
admin.site.register(GoodsSPU, BaseModelAdmin)
admin.site.register(GoodsType, BaseModelAdmin)
admin.site.register(GoodsImage, BaseModelAdmin)
admin.site.register(IndexGoodsBanner, BaseModelAdmin)
admin.site.register(IndexTypeGoodsBanner, BaseModelAdmin)
admin.site.register(IndexPromotionBanner, BaseModelAdmin)

通过Nginx访问静态页面

上面生成的静态页面只能够通过django服务器ip:8000/static/index.html网址访问,但是我们想要的是用户直接输入ip地址后就能访问静态页面,于是需要Nginx帮忙。在Nginx配置文件(/usr/local/nginx/conf/nginx.conf)中,修改如下配置:

server {
        listen       80;
        server_name  localhost;
        #charset koi8-r;
        #access_log  logs/host.access.log  main;
        location /static {
            alias /home/gong/study/projects/dailyfresh/static/;
        }
        location / {
            #root   html;
            root /home/gong/study/projects/dailyfresh/static/;
            index index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

在浏览器中输入IP地址后不输入端口号时,则默认访问的是80端口,location相当于是url匹配器,从上往下进行匹配,若符合ip/static,则显示 /home/gong/study/projects/dailyfresh/static/ 下面的index.html文件,若ip地址后面什么都没有输入,则也显示/home/gong/study/projects/dailyfresh/static/下面的index%文件

在浏览器中输入http://192.168.183.129/static/http://192.168.183.129时访问的就是生成的静态页面

何时访问静态化首页,何时访问正常动态化的首页

当我们访问静态化首页时,访问的地址是http://192.168.183.129,默认的是80端口,访问到的服务器是Nginx服务器

当我们访问动态化首页时,访问的地址是http://192.168.183.129:8000,是8000端口,访问到的是服务器是Django服务器

但是部署上线后,最后暴露给用户的地址肯定只有一个,而不是将上述两个地址给用户,让用户选择访问哪个页面,这里就需要在用户和(Nginx、Django)服务器之间,再搭一台Nginx服务器,通过这台Nginx服务器给用户暴露一个浏览的地址(比如为http://192.168.183.130),然后让服务器判断决定用户最终访问的服务器是哪个(比如当用户直接输入http://192.168.183.130时,中间的Nginx最终让其访问的是Nginx指向的静态首页,当用户输入http://192.168.183.130/index时,中间的Nginx最终让其访问的是Django服务器的动态首页)。

缓存首页数据信息

当我们不是访问静态页面的首页,而是访问正常动态首页时,每次访问也依然需要重新查询数据库,而其实查出来的数据基本都是一样的,除非后台管理员修改了后台数据,这时为了避免重复查询,可以使用django的缓存机制,将第一次查出来的数据放入django服务器的缓存中(注意不是浏览器的缓存),后续访问页面时,先在缓存中查询数据是否存在,存在即直接取出数据,不存在即重新查询数据。

配置django缓存

缓存可以存在数据库或者文件系统中,一般我们都会存在内存型数据库汇总,前面登录配置session时(DJANGO-天天生鲜项目从0到1-003-用户模块-登录),已经配好了将缓存存在redis数据库中

CACHES = {
  "default": {
    "BACKEND": "django_redis.cache.RedisCache",
    "LOCATION": "redis://127.0.0.1:6379/1",
    "OPTIONS": {
      "CLIENT_CLASS": "django_redis.client.DefaultClient",
    }
  }
}

使用django缓存,cache.get(key),cache.set(key, data, timeout)

在首页view.py中,在查询数据库信息前,先通过cache.get从缓存中查询是否存在需要的数据,若不存在则在查询完一些公用的数据库信息之后,将这些公用信息通过cache.set存在缓存中

from django.core.cache import cache

class IndexView(View):
    '''首页视图'''
    template_name = 'goods/index.html'
    def get(self, request):
        '''显示首页'''
        # 从缓存汇总获取数据
        context = cache.get('index_data')
        if not context:
            # 获取数据库信息
            context = get_index_data()
            # 设置缓存,3600秒过期
            print('设置缓存')
            cache.set('index_data', context, 3600)

        # 获取购物车数量,购物车存储格式为:cart_userid : {'goodsid': quantity}
        cart_count = get_cart_count(request)
        context['cart_count'] = cart_count
        return render(request, self.template_name, context)

删除缓存,cache.delete(key)

同样在后台管理员修改了首页数据库信息时,需要将原来的缓存删除掉,等删除后再次访问首页时,重新设置新的缓存信息

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

猜你喜欢

转载自www.cnblogs.com/gcxblogs/p/12813541.html