django开发的网站优化:页面静态化+数据缓存

  • 目的:网站本身性能的优化,减少数据库的查询次数.
  • 防止恶意的攻击.DDOS攻击

页面静态化

把数据库查询到的内容,写入到静态index.html页面(利用celery异步)

cdlery_tasks/tasks.py 定义一个任务:

from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner

@app.task
def generate_static_index_html():
    '''首页'''
    # 获取商品的种类信息
    types = GoodsType.objects.all()
    for type in types:
        print('*******商品分类名称:' + type.name)
    # 获取首页轮播商品信息
    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:  # 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定义上下文
    # context = RequestContext(request, context) #没有request所以忽略
    # 模板渲染
    static_index_html = temp.render(context)

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

基本与动态显示页面方法一样,只不过在代码后半部分,写一个 write方法,把首页信息,写入文件.注意,这个文件写在 任务处理者目录下面.

nginx配置

去修改任务处理者所在电脑的nginx配置文件,server 80端口,内容:

sudo vi /usr/local/nginx/conf/nginx.conf

在server 80端口添加如下 location的配置

server {
        listen  80;
        server_name localhost;
        location /static{
            alias /home/jy/python/dailyfresh_celery任务处理者/dailyfresh/static/;    
        }
        location / {
            root /home/jy/python/dailyfresh_celery任务处理者/dailyfresh/static/;
            index index.html index.htm;
        }

.......省略
}

后台页面:

后端管理员,添加删除首页信息的时候,调用任务处理者,重新生成首页静态页面.
所以在 goods / admin.py 中写入如下代码:

from goods.models import GoodsType, IndexPromotionBanner

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, form, change)

        # 发出任务让celery worker重新生成首页静态页面
        from celery_tasks.takss import generate_static_index_html
        generate_static_index_html.delay()

admin.site.register(IndexPromotionBanner, IndexPromotionBannerAdmin)

测试下:

  • 正常访问首页是: 127.0.0.1:8000 主机,动态生成页面(从数据库查询的信息)
  • nginx帮你生成的静态页面是: 127.0.0.1:80 ,这个页面在celer任务处理者 static目录下 (删除,看是否 会重新生成,或者修改里面代码,测试)

测试时,访问后台管理页面,在后台添加删除一个模块,然后重新访问 上面2个页面,看是否一致.


使用缓存

将处理计算的结果先临时保存起来,下次使用的时候可以先直接使用,如果没有这个备份的数据,重新进行计算处理
将缓存数据保存在内存中 (本项目中保存在redis中)
django底层缓存API
类: django.core.cache.cache

from django.core.cache import cache

基本用法:
最基本的借口是set(key, value, timeout)get(key)

开头尝试从缓存中获取数据

context = cache.get('index_page_data')

如果不存在,

if context is None:

开始正常代码流程:从数据库中读取数据
结尾,把读到的数据设置到缓存里.

cache.set('index_page_data', context, 3600)

from django.core.cache import cache
class IndexView(View):
    '''首页'''
    def get(self, request):
        '''显示首页'''
        #尝试从缓存中获取数据
        context = cache.get('index_page_data')
        if context is None:
            #缓存中没有数据:
            print('设置缓存')
            #获取商品的种类信息
            types = GoodsType.objects.all()
            for type in types:
                print('*******商品分类名称:'+type.name)
            #获取首页轮播商品信息
            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: #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}

            #设置缓存
            cache.set('index_page_data', context, 3600)

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

        #组织模板上下文
        context.update(cart_count=cart_count)
        # context = {'types':types,
        #            'goods_banners':goods_banners,
        #            'promotion_banners':promotion_banners,
        #            'cart_count':cart_count}

        return render(request, 'index.html', context)

还要修改后台管理类里,如果有增加或者删除操作,则清空缓存.(此流程类似与页面静态化.
在上述admin.py文件delete_modelsave_model函数中,分别加入下面清除缓存的代码.

        #清楚首页缓存
        cache.delete('index_page_data')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 大多数 Nginx 新手都会频繁遇到这样一个困惑,那就是当同一个location配置块使用了多个 Nginx 模块...
    SkTj阅读 7,834评论 0 12
  • 经管 何大川 序言 世界经历了数次生化战争以及化工、核辐射的大面积污染,土地和水环境被彻底摧毁了。近几十年里,因为...
    低维量子系统阅读 315评论 0 0
  • 昨晚,油桐花开了 花瓣大的像夜神的唇 粉红色的梦 在花口吹奏出诱惑的曲子。 这不是开花的季节, 片片掉落,布满了树...
    白鹤来翔阅读 156评论 0 1
  • 第1章 认识JS JavaScript能做什么?1.增强页面动态效果(如:下拉菜单、图片轮播、信息滚动等)2.实现...
    mo默22阅读 1,345评论 0 5
  • 奇迹分享: 1、今天我去的哪里(超市、健身房…)都很容易进入放空的状态,当下其实真的不论什么时候,只要在做感觉好的...
    NancyIsee阅读 923评论 0 0