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

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

  1. Redis添加历史浏览记录

    参考资料 http://redisdoc.com/index.html http://redis-py.readthedocs.io/en/latest/#indices-and-tables 1.什 ...

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

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

  3. JS制作一个通用的商城版历史浏览记录

    正在开发一个b2c的国外商城,昨天做了一个历史浏览记录发出来跟大家分享一下. JS: //cookie相关函数 function getCookieVal(offset) {    var endst ...

  4. position:搜索框显示历史浏览记录

    absolute 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位. 元素的位置通过 "left", "top", "righ ...

  5. 使用Cookie实现用户商品历史浏览记录

    该功能分为四个模块: 1. 获取所有商品并以链接的形式显示 out.write("网站商品: <br/>"); Map<String, Book> book ...

  6. redis的介绍与操作及Django中使用redis缓存

    redis VS mysql的区别 """ redis: 内存数据库(读写快).非关系型(操作数据方便) mysql: 硬盘数据库(数据持久化).关系型(操作数据间关系) ...

  7. Thinkphp3.2 Redis缓存session

    Thinkphpsession缓存没有redis类库 Redis.class.php放在Library/Think/Session/Driver/下: <?php /** * +-------- ...

  8. 基于Redis缓存几十万条记录的快速模糊检索的功能实现(c#)

    在开发一套大型的信息系统中,发现很多功能需要按公司查询,各个模块在实现时都是直接查数据库进行模糊检索,虽然对表进行向各个应用的库中进行了同步,但是在使用中发现,模糊检索公司时还是比较卡,原始的查询数据 ...

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

    /** * history_teacher.jsp中的js,最近浏览名师 * @version: 1.0 * @author: mingming */ $(function(){ getHistory ...

随机推荐

  1. Java 从入门到进阶之路(五)

    之前的文章我们介绍了 Java 的循环结构,本章我们来看一下 Java 的数组 数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同. 数组 - 相同数据类型的元 ...

  2. KVC&KVO&运行时

    运行时:要先了解程序运行的三个阶段 1.编译阶段:clang将OC代码转换成C++,查看运行机制调用的方法 2.链接阶段:与我们使用到得库文件进行链接 3.运行阶段:我们要谈的运行时主要针对这个阶段, ...

  3. HDU4578 线段树(区间更新 + 多种操作)和平方,立方

    参考:https://www.cnblogs.com/H-Vking/p/4297973.html 题意: 虽然是比较裸的线段树,但是比较麻烦,并且有很多细节需要考虑,对着别人的ac代码debug了一 ...

  4. hdu 5887 Herbs Gathering (dfs+剪枝 or 超大01背包)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5887 题解:这题一看像是背包但是显然背包容量太大了所以可以考虑用dfs+剪枝,贪心得到的不 ...

  5. lightoj 1036 - A Refining Company(简单dp)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1036 题解:设dp[i][j]表示处理到(i,j)点时的最大值然后转移显然是 ...

  6. 题解 bzoj 2151 种树

    题意 传送门 手写堆大法好啊,题解貌似没有结构体堆的做法,思路有些像配对堆,关于配对堆请自行百度,因为本蒟蒻不会.. 以下是蒟蒻的做法:建立一个大根堆a维护最大价值里面存入它的编号以及价值.听说配对堆 ...

  7. react页面内嵌微信二维码 和 自定义样式 以及 微信网页共用unionId问题

    在react页面内嵌“微信二维码”,实现PC端通过微信扫码进行登录.首先去微信开放平台注册一个账号,创建一个网站应用,提交网站备案审核,获取appid和appsecret:其他开发流程根据微信文档来进 ...

  8. 编码神器Lombok,学会后开发效率至少提高一倍!

    Lombok会利用注解自动生成javaBean中的getter.setter.equals.toString等一系列方法,大大提供开发效率,本文详细介绍下Lombok的安装及使用. 本文目录 一.Lo ...

  9. sublime,webstrom,vscode的使用感受,以及对于vue和webpack的支持,还有一些快捷键使用心得

    从最开始用sublime3到webstrom再到vscode,我的感觉如下: sublime首次加载项目文件速度较快,每次装插件有点麻烦,插件很丰富,也很好用. webstrom首次加载项目文件速度奇 ...

  10. 了解css中px、em、rem的区别并使用Flexible实现vue移动端的适配

    本人java菜鸟一名,若有错误,还请见谅. 1.px和em和rem的定义和区别 px:px像素,是相对单位,相对于屏幕的分辨率而言,也就是说,当屏幕的分辨率不同那么px相同,实际看到的大小也会不同. ...