django中使用redis实现用户操作历史记录历程

“小王,个人中心要设置一个查看操作文档历史记录的功能,你实现一下”

小王拿到这个需求不假思索,so easy,使用redis的列表解决就OK了,把用户id作为键,列表中存文档的id,设置一个列表最大长度,对列表进行去重,不就O了吗

小王一顿操作猛如虎,代码写好了

# 连接到redis
redis_conn = get_redis_connection('history')
# 设置key值
redis_key = 'history_%s' % user.id
# 使用管道
pl = redis_conn.pipeline()
# 去除列表中与要存入doc_id相同的元素
pl.lrem(redis_key, 0, doc_id)
# 从左将id侧插入列表
pl.lpush(redis_key, doc_id)
# 将超过规定长度的doc_id删除
pl.ltrim(redis_key, 0, constants.USER_OPERATE_HISTORY_MAX_LIMIT - 1)
pl.execute()

从此小王和手机过上了没羞没臊的生活,可是好景不长,过了半天,需求改了

“小王,代码写的不错,运行起来也没问题,现在历史记录需要加一下操作时间和具体操作”

小王笑呵呵地放下了手机,嘴里最终还是没能说出心里千呼万唤的“mmp”,一边寻思着还能不能继续用列表去存,把包含文档id,操作时间,具体操作写到一个字典里,把字典转换成字符串,再将字符串存入列表中,呵呵,easy。

小王正准备拿出尘封半天的82年的祖传键盘,突然脑子里闪过一个念头,去重是个问题啊!小王一激动,一巴掌拍到大腿上,险些把手掌拍成粉碎性骨折,多亏单身多年手上的老茧,勉强保住了女朋友。

保存多个属性,小王稍加思索就想到了hash,用户id作为键,hash内部文档id作为键,直接解决了去重的问题,激动得小王猛地甩了一下头发,继续拿出他82年的祖传键盘,杠几杠几开始敲

# 连接到redis
redis_conn = get_redis_connection('history')
# 设置key值
redis_key = 'history_%s' % user.id
dict = {}
datetime_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dict["doc_id"] = doc_id
dict["operation"] = operation
dict["datetime"] = datetime_str
# 将字典转为字符串
cart_pickle = pickle.dumps(dict)
str = base64.b64encode(cart_pickle).decode()
redis_conn.hset(redis_key, doc_id, str)

写到这里小王突然意识到一个问题,他战战巍巍地放下了随他征战多年的键盘,说时迟那时快,一巴掌甩到自己的脸上,比大腿那一下劲儿只大不小,这一下倒好,把他多年的歪嘴给打歪到另一边去了,hash解决了去重的问题,但是没解决排序的问题!一边思考着,一边摸着歪向另一边的嘴,担心回老家了和爹妈不好解释。

又是灵光一闪,这感觉像是被雷电击中,又像是阴沉的天空,突然裂开,射进一缕阳光,hash+list,hash来存数据去重,list用来排序。

redis_conn = get_redis_connection('history')
pl = redis_conn.pipeline()
redis_hash_key = 'history_hash_%s' % user.id
redis_list_key = 'history_list_%s' % user.id
datetime_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dict["doc_id"] = doc_id
dict["operation"] = operation
dict["datetime"] = datetime_str
# 将字典转为字符串
cart_pickle = pickle.dumps(dict)
str = base64.b64encode(cart_pickle).decode()
pl.hset(redis_hash_key, doc_id, str)
if redis_conn.llen(doc_id) > constants.USER_OPERATE_HISTORY_MAX_LIMIT:
    # 取list中最后一个元素对应的doc_id,在hash中去掉该键值对
    pl.hdel(pl.lindex(redis_list_key,-1))
# 去除列表中与要存入doc_id相同的元素
pl.lrem(redis_list_key, 0, doc_id)
# 从左将id侧插入列表
pl.lpush(redis_list_key, doc_id)
# 将超过规定长度的doc_id删除
pl.ltrim(redis_list_key, 0, constants.USER_OPERATE_HISTORY_MAX_LIMIT - 1)
pl.execute()

取元素的时候首先遍历list,取到doc_id后,根据doc_id以此在hash表中取到对应的值,再将值还原成字典返回

# 取用户id
user_id = request.user.id
# 连接数据库
redis_conn = get_redis_connection('history')
dict_list = []
# 获取list中文档id列表
doc_list = redis_conn.lrange('history_list_%s' % user_id,0,-1)
for doc_id in doc_list:
    # 根据文档id以此取对应的值
	user_hash = redis_conn.hget('history_hash_%s' % user_id,doc_id)
    # 将字符串转化为字典
    value = pickle.loads(base64.b64decode(user_hash))
    # 添加到列表中
    dict_list.append(doc_dict)
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值