Django之使用redis缓存session,历史浏览记录,首页数据实现性能优化

Redis缓存session

配置Django缓存数据到redis中

# diango的缓存配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # 用户的session信息,历史浏览记录存储在redis数据库9中
        "LOCATION": "redis://127.0.0.1:6379/9",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

配置session信息缓存在redis中

# 配置session存储在前面配置的redis数据库中
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

保存用户cookie,session信息

# 与数据库的数据进行校验用户密码正确性
user = authenticate(request, username=username, password=password)
# 业务处理:用户登录
# 返回应答
if user is not None:
    # 用户名密码正确
    if user.is_active:
        # 用户已激活
        # 记录用户的登录状态
        login(request, user)
        # 获取接下来要访问的地址,默认访问主页
        next_url = request.GET.get("next", reverse("goods:index"))
        response = redirect(next_url)
        # 判断是否记住用户名
        if remember == "on":
            response.set_cookie("username", username, max_age=7*24*3600)
        else:
            response.delete_cookie("username")
        return response

Redis缓存历史浏览记录

链接Redis数据库

链接redis数据库有两种:

  • 1.使用redis默认的StrictRedis链接
  • 2.使用redis提供的get_redis_connection方法链接default配置;

方式一:

# 使用redis默认的方式与django链接
# from redis import StrictRedis
# sr = StrictRedis(host="localhost", port=6379, db=9)

方式二:

from django_redis import get_redis_connection
con = get_redis_connection(‘default‘)  # 这里的default指的是settings配置中CACHE的default配置

缓存历史浏览记录

首先确定我们的需求,是一个用户保存一个浏览商品id集合,然后确定是以redis的hash格式存储,存储类似于

history_userid:[goods1, goods2, goods3]

然后我们要考虑情况,比如我们原来浏览过一条商品,现在再浏览一遍,那么就要把这个商品的位置提到最前面去,怎么处理?

  • 在这里我们选择的是如果存在该商品,就先删除,再往最左边插入这条数据,可以使用redis提供的 lrem 方法。
  • 将最新浏览的记录放在最前面,当我们获取缓存中的浏览商品id集合数据,应该是根据id集合的顺序来确定商品顺序的,这里我们可以规定最新的浏览记录放在集合的最左边,使用的是redis的lpush方法。
  • 还有只保存固定条数的浏览记录,过期的就不保存,使用redis的ltrim方法。

同时下面也例举了如何获取历史浏览记录id集合。

from django_redis import get_redis_connection

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
    # 移除相同的记录
    conn.lrem(history_key, 0, goods_id)
    # 从左侧添加历史浏览记录
    conn.lpush(history_key, goods_id)
    # 只保留最新的五个历史浏览记录
    conn.ltrim(history_key, 0, 4)
    # 获取历史浏览记录的商品id表
    # sku_ids = conn.lrange(history_key, 0, 4)
    # print("goods.view,历史浏览记录商品id表", sku_ids)

获取历史浏览记录

获取用户历史浏览商品id可以使用redis的lrange加上始终索引来获取指定数量数据,
获取历史浏览商品id后,因为需要根据redis中的顺序来确定商品显示顺序,可以用两种方式来获取商品具体信息:

  • 1.循环从redis获取的商品id列表,根据id获取对应的商品;
  • 2.根据商品id列表获取商品列表,循环从redis获取的商品id列表,在循环中再次循环商品列表,判断如果商品id等于循环的商品列表的id,就添加入商品表中。

方式一:

# 从数据库查询用户浏览商品的具体信息
# goods_li = GoodsSKU.objects.filter(id__in=sku_ids)
# goods_res = []
# for a_id in sku_ids:
#     for goods in goods_li:
#         if a_id == goods.id:
#             goods_res.append(goods)

方式二:

# 遍历获取用户浏览的商品信息
goods_li = []
for id in sku_ids:
    goods = GoodsSKU.objects.filter(id=id)
    goods_li.append(goods)

获取用户历史浏览记录代码

class UserInfoView(LoginRequiredMixin, View):
    """用户中心-信息页"""
    def get(self, request):
        """返回用户中心信息页面"""
        user = request.user
        # 获取用户的历史浏览记录
        con = get_redis_connection(‘default‘)  # 这里的default指的是settings配置中CACHE的default配置
        history_key = ‘history_%d‘ % user.id
        # 获取用户最新浏览的5个历史记录
        sku_ids = con.lrange(history_key, 0, 4)

        # 从数据库查询用户浏览商品的具体信息
        # goods_li = GoodsSKU.objects.filter(id__in=sku_ids)
        # goods_res = []
        # for a_id in sku_ids:
        #     for goods in goods_li:
        #         if a_id == goods.id:
        #             goods_res.append(goods)
        # 遍历获取用户浏览的商品信息
        goods_li = []
        for sku_id in sku_ids:
            goods = GoodsSKU.objects.get(id=sku_id)
            goods.image = settings.MEDIA_PATH + str(goods.image)
            goods_li.append(goods)
        context = {
            "page": "page",
            "address": address,
            "goods_li": goods_li
        }
        return render(request, "user_center_info.html", context)

Redis缓存网站首页数据

Django缓存相关文档:https://yiyibooks.cn/xx/django_182/topics/cache.html
缓存文档中,提供有三种缓存方式,站点级缓存,单个view缓存,模板片段缓存,但都不适合我们,这里我们是直接操作底层缓存api。

首页数据的缓存:把页面使用的数据存放在缓存中,当要使用这些数据时,就先从缓存中获取,如果获取不到,就再去数据库中获取,减少数据库的查询次数。

缓存首页数据,使用的还是redis进行缓存,如果你没看前面是独立做这一步的话,要进行如下配置,前面已经配置过的。

# diango的缓存配置
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # 用户的session信息,历史浏览记录存储在redis数据库9中
        "LOCATION": "redis://127.0.0.1:6379/9",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}

缓存首页数据

缓存数据,我们在这里用的是django自带的cache函数,它会帮我们将数据缓存到一定的地方,我们这里配置的是将数据缓存到redis中,即cache函数会帮我们将数据缓存到redis中。

cache函数需要三个参数,第一个是缓存的key,即你要给缓存的数据起一个名字,我们可以理解为python中的字典,第二个参数是要缓存的数据,第三个参数是缓存数据过期时间。

使用cache函数缓存首页数据代码

class IndexView(View):
    def get(self, request):
        # 从缓存中获取数据
        context = cache.get("index_page_data")
        # 如果缓存中没有数据,就去数据库中获取数据
        if context is None:
            print("缓存数据ing")
            # 获取商品的种类信息
            types = GoodsType.objects.all()
            # 获取首页轮播商品信息
            goods_banners = IndexGoodsBanner.objects.all().order_by("index")
            # 获取首页促销活动信息
            promotions_banners = IndexPromotionBanner.objects.all().order_by("index")
            # 获取首页分类商品展示信息
            for type in types:
                # 获取type分类首页分类商品的图片展示对象信息
                image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1)
                # 获取type分类首页分类商品的文字展示对象信息
                title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0)
                # 动态给type增加属性,分别保存首页分类商品的图片展示信息和文字展示信息
                type.image_banners = image_banners
                type.title_banners = title_banners
            context = {
                "types": types,
                "goods_banners": goods_banners,
                "promotions_banners": promotions_banners,
            }
            # 设置缓存
            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)

同时在这里提醒一下,如果你对Redis不够熟悉的话,不用去拘泥于使用redis的哪种格式缓存首页数据,我们只需要知道redis是一种内存数据库即可,django配置了将缓存放入redis即内容中,在这里django的cache已经帮我们做好了怎么缓存,我们只需要调用即可。

首页缓存数据的更新

当管理员在后台修改首页信息对应的数据表中的数据时,我们就需要更新首页的缓存数据了。

在这里我们实现的方式是直接清空缓存中的首页数据,这样当下一个用户去访问首页时,因为没有从缓存中查到数据,就会从数据库获取数据并且重新存储到缓存中了,清除缓存使用cache.delete()方法。

下面直接贴代码,置于实现原理,可以参考  https://www.cnblogs.com/yifchan/p/python-1-37.html 最后一节

from django.contrib import admin
from django.core.cache import cache
from goods.models import GoodsType, GoodsSKU, Goods, GoodsImage, IndexGoodsBanner, IndexTypeGoodsBanner, IndexPromotionBanner

class BaseModelAdmin(admin.ModelAdmin):
    """当后台数据库数据改动时清空缓存使重新缓存首页数据"""
    def save_model(self, request, obj, form, change):
        """当更新或者新增数据时调用"""
        super().save_model(request, obj, form, change)
        # 清除首页的缓存数据
        cache.delete("index_page_data")

    def delete_model(self, request, obj):
        """当删除数据时调用"""
        super().delete_model(request, obj)
        # 清除首页的缓存数据
        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(GoodsSKU)
admin.site.register(Goods)
admin.site.register(GoodsImage)
admin.site.register(IndexGoodsBanner, IndexGoodsBannerAdmin)
admin.site.register(IndexTypeGoodsBanner, IndexTypeGoodsBannerAdmin)
admin.site.register(IndexPromotionBanner, IndexPromotionBannerAdmin)

app-goods/admin.py

原文地址:https://www.cnblogs.com/yifchan/p/python-1-38.html

时间: 2024-10-19 08:48:43

Django之使用redis缓存session,历史浏览记录,首页数据实现性能优化的相关文章

redis存储用户历史浏览记录

1:什么时候需要添加浏览记录 访问商品详情页的时候 2:什么时候取出浏览记录 访问用户个人中心的时候 用户查看商品的历史浏览记录存成什么格式: history_用户id:[商品id,商品id] 添加用户浏览记录: # 添加用户的历史记录history_用户id:[商品id,商品id,商品id]conn = get_redis_connection('default')history_key = 'history_%d' % user.id# 用redis的lrem方法将最早的那一条浏览记录移除掉

destoon系统开发-最新利用浏览器的cookie 做历史浏览记录

  注意: 代码 放在要显示的为 (一般放在详情页),注意本教程不入库,直接利用浏览器的 cookie 缓存判断    <!--历史浏览记录 S--> <div class="column_box mt_10"> <div class="column_title">历史浏览记录</div> <div class="box_body_new"> <?php $MOD_name = &

js操作Cookie,实现历史浏览记录

/** * history_teacher.jsp中的js,最近浏览名师 * @version: 1.0 * @author: mingming */ $(function(){ getHistory(); }); var historyCount=4; //保存历史记录个数 /** * 增加浏览历史记录 * @param id 编号 * @param name 姓名 * @param photo 照片 * @param grade 年级 * @param subject 科目 * @retur

H5缓存机制浅析-移动端Web加载性能优化【干货】

转载:H5缓存机制浅析-移动端Web加载性能优化[干货] 作者:贺辉超,腾讯游戏平台与社区产品部 高级工程师 目录 1 H5缓存机制介绍 2 H5缓存机制原理分析 2.1 浏览器缓存机制 2.2 Dom Storgage(Web Storage)存储机制 2.3 Web SQL Database存储机制 2.4 Application Cache(AppCache)机制 2.5 Indexed Database (IndexedDB) 2.6 File System API 3 移动端Web加载

H5 缓存机制浅析 移动端 Web 加载性能优化

1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5 引入的离线存储,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问. H5 应用程序缓存为应用带来三个优势: 离线浏览 用户可在应用离线时使用它们 速度 已缓存资源加载得更快 减少服务器负载 浏览器将只从服务器下载更新过或更改过的资源. 根据标准,到目前为止,H5 一共有6种缓存机制,有些是之前已有,有些是 H5 才新加入的. 浏览

Django中使用Redis缓存

目录 Redis数据库 Redis vs MySQL Redis vs Memcache Redis操作 Redis数据库 Python使用Redis Redis数据库 Redis vs MySQL redis: 内存数据库(读写块).非关系型(操作数据方便) MySQL:硬盘数据库(数据持久化).关系型(操作数据间关系) 大量访问临时数据,采用redis数据库更优 Redis vs Memcache Redis 操作字符串.列表.哈希.无序集合.有序集合 支持数据持久化,有一部分数据存在硬盘中

redis缓存+session 实现单点登录

一.单点登录介绍 单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 同域下:单点登录是巧用了Cookie顶域的特性. 不同域下:如果是不同域呢?不同域之间Cookie是不共享的,怎么办? 这个是使用CAS流程,单点登录的标准流程. 相关详情:https://yq.aliyun.com/articles/636281    https://blog.csdn.n

Java电商项目-6.实现门户首页数据展示_Redis数据缓存

目录 项目的Github地址 需求介绍 搭建Redis集群环境 下面先描述单机版redis的安装 下面将进行Redis3主3从集群环境搭建 基于SOA架构, 创建门户ashop-portal-web门户项目 实现门户首页商品类目显示 实现门户首页大广告轮播 实现商品类目缓存 实现大广告缓存, 缓存同步 缓存同步 项目的Github地址 需求介绍 为了缩短用户看到首页信息的时间, 我们把首页显示的类目信息, 广告等数据放到Redis缓存中, 这样就不用通过耗时的数据库操作获取数据, 而是直接从Re

使用 Redis 缓存来实现用户最近浏览的商品列表

一.如何使用 Redis 来缓存来实现最近浏览的商品列表? 首先我们要确定一个两个点,最近浏览的商品肯定是一个存一个取的操作. 那么就可以确定以下几个问题: 最近浏览的记录肯定是要有失效时间的 这里可以使用缓存(Redis等),缓存可以设置失效时间(最大设置为一个月). 如果使用关系型数据库,还需要定时清楚,就很不符合实际需求. 最近浏览记录肯定是要有个数限制的,不可能记录所有的浏览记录 如果使用Redis来实现的话,Redis 中有 LTRM 来修建,以保证存储的浏览条数. 需要在哪里添加保存