使用Redis构建简易社交网站(2)-处理用户关系

目的

本文目的:实现用户关注和取消关注功能。(完整代码附在文章末尾)

相关知识

在我之前的文章 《使用Redis构建简易社交网站(1)-创建用户与动态界面》中提到了如何实现简易社交网站中创建新用户和创建新动态功能。

那这篇文章将教会你掌握:1.redis基本命令,2.python基本命令。

redis基本命令

zscore:返回有序集合中指定成员的分值。

conn = redis.Redis()
conn.zscore("testzset", "member1")
conn.zscore("testzset", "not_exists_member")

testzset内容如下:

执行结果:

100.0
None

zadd:将成员加入到有序集合中,并确保其在正确的位置上。

conn = redis.Redis()
conn.zadd("testzset", "member2", 3)
conn.zadd("testzset", "member1", 2)
conn.zadd("testzset", "member3", 1)

执行后:

member3
member1
member2

执行结果:111

hincrby:为哈希中指定域的值增加增量 increment,用于统计。

conn = redis.Redis()
conn.hincrby("testhash", "field1", 1)

执行前:

{'field1': '1'}

执行后:

{'field1': '2'}

zrem:从有序集合中移除指定成员。

conn = redis.Redis()
conn.zrem("testzset", "member1")

执行前:

member3
member1
member2

执行后:

member3
member2

执行结果:1

pipeline:将多条命令按照先后顺序放进一个队列中,一般配合execute一同使用,原子性(atomic)地执行队列里的命令。

conn = redis.Redis()
pipe = conn.pipeline(True) # 事务开始
pipe.incr("counter")
pipe.incr("counter")
pipe.incr("counter")
pipe.execute() # 事务执行

执行结果:[1, 2, 3],通过下标即可获取对应命令的执行结果。

python基本命令

使用格式化拼接字符串:

"My name is %s, I'm %i years old"%('educoder', 2)

执行结果:"My name is educoder, I'm 2 years old"

返回当前时间的时间戳。

  1. time.time()

将字符串转换为整型数据:

  1. int("1")

执行结果:1

取一个数的相反数:

  1. a = 1
  2. b = -a
  3. print b

执行结果:-1

实战例题

编写 follow(uid, other_uid) 函数,实现关注用户的功能,具体参数与要求如下:

  • 方法参数uid为当前用户编号,other_uid为被关注的用户编号;
  • 避免重复关注的实现:如果被关注的用户编号已经在当前用户的关注列表following:{uid}中,则不重复关注,直接返回None
  • 建立关注关系的实现:使用事务一次性提交:
    • 将被关注的用户编号加入到当前用户的关注列表following:{uid}中,分值为当前时间戳。
    • 将当前用户编号加入到被关注用户的粉丝列表中followers:{other_uid},分值为当前时间戳。
  • 修改统计数据的实现:若关系建立成功,则使用事务一次性提交:
    • 将当前用户详情user:{uid}中的关注数following1
    • 将被关注用户详情user:{other_uid}中的粉丝数followers1
  • 返回执行结果的实现:返回True

编写 unfollow(uid, other_uid) 函数,实现取消关注的功能,具体参数与要求如下:

  • 方法参数uid为当前用户编号,other_uid为被取消关注的用户编号;
  • 避免重复取消关注的实现:如果被关注的用户编号已经不在当前用户的关注列表following:{uid}中,则不重复取消关注,直接返回None
  • 删除关注关系的实现:使用事务一次性提交:
    • 从当前用户的关注列表following:{uid}中移除被取消关注用户编号。
    • 从被取消关注用户的粉丝列表中followers:{other_uid}移除当前用户编号。
  • 修改统计数据的实现:若关系删除成功,则使用事务一次性提交:
    • 将当前用户详情user:{uid}中的关注数following1
    • 将被取消关注用户详情user:{other_uid}中的粉丝数followers1
  • 返回执行结果的实现:返回True

注意: 关注列表和粉丝列表均为有序集合,存储成员时,分值均为当前时间戳; 用户详情为上一关中创建的哈希结构。

测试输入:

  1. 9
  2. 4

预期输出:

测试 follow 方法...
用户 9 关注 用户 4
关注结果: True
用户 9 的关注列表内容为: ['4']
用户 4 的粉丝列表内容为: ['9']
用户 9 的用户详情为: {'login_name': 'test_user9', 'posts': '0', 'real_name': 'Test user9', 'followers': '0', 'following': '1', 'id': '9'}
用户 4 的用户详情为: {'login_name': 'test_user4', 'posts': '0', 'real_name': 'Test user4', 'followers': '1', 'following': '0', 'id': '4'}用户 9 再次关注 用户 4
关注结果: None测试 unfollow 方法...
用户 9 取消关注 用户 4
取消关注结果: True
用户 9 的关注列表内容为: []
用户 4 的粉丝列表内容为: []
用户 9 的用户详情为: {'login_name': 'test_user9', 'posts': '0', 'real_name': 'Test user9', 'followers': '0', 'following': '0', 'id': '9'}
用户 4 的用户详情为: {'login_name': 'test_user4', 'posts': '0', 'real_name': 'Test user4', 'followers': '0', 'following': '0', 'id': '4'}用户 9 再次取消关注 用户 4
取消关注结果: None

 code.py

#code.py
#-*- coding:utf-8 -*-import re
import time
import redisconn = redis.Redis()# 关注用户
def follow(uid, other_uid):# 请在下面完成要求的功能#********* Begin *********#fkey1 = "following:%s"%(uid)fkey2 = "followers:%s"%(other_uid)if conn.zscore(fkey1, other_uid):return Nonenow = time.time()pipe = conn.pipeline(True)pipe.zadd(fkey1, other_uid, now)pipe.zadd(fkey2, uid, now)following, followers = pipe.execute()pipe.hincrby("user:%s"%(uid), 'following', int(following))pipe.hincrby("user:%s"%(other_uid), 'followers', int(followers))pipe.execute()return True#********* End *********## 取消关注
def unfollow(uid, other_uid):# 请在下面完成要求的功能#********* Begin *********#fkey1 = "following:%s"%(uid)fkey2 = "followers:%s"%(other_uid)if not conn.zscore(fkey1, other_uid):return Nonepipe = conn.pipeline(True)pipe.zrem(fkey1, other_uid)pipe.zrem(fkey2, uid)following, followers = pipe.execute()pipe.hincrby("user:%s"%(uid), 'following', -int(following))pipe.hincrby("user:%s"%(other_uid), 'followers', -int(followers))pipe.execute()return True#********* End *********## 创建新用户
def create_user(login_name, real_name):login_name = login_name.lower()if conn.hget("users", login_name):return Noneuid = conn.incr("user:id")pipe = conn.pipeline(True)pipe.hset("users", login_name, uid)pipe.hmset("user:%i"%(uid), {'login_name': login_name,'id': uid,'real_name': real_name,'followers': 0,'following': 0,'posts': 0,'last_signup': time.time(),})pipe.execute()return uid# 为用户创建新动态
def create_post(uid, content):pipe = conn.pipeline(True)pipe.hget("user:%i"%(uid), 'login_name')pipe.incr("post:id")login_name, pid = pipe.execute()if not login_name:return Nonepipe.hmset("post:%i"%(pid), {'id': pid,'uid': uid,'content': content,'posted': time.time(),'user_name': login_name,})pipe.hincrby("user:%i"%(uid), 'posts')pipe.execute()return pid

read.py

#read.py
#-*- coding:utf-8 -*-import os
import sys
import time
import redis
import pprint
from code import *conn = redis.Redis()
retry_time = 0
while True:try:conn.ping()breakexcept redis.exceptions.ConnectionError:os.system("redis-server > /dev/null 2>&1 &")retry_time += 1if retry_time > 3:breakpipe = conn.pipeline(True)
pipe.delete("users", "user:id")
keys = conn.keys("user:*") + conn.keys("followers:*") + conn.keys("following:*")
for key in keys:pipe.delete(key)
pipe.execute()# 创建测试数据
join_str = " "
for i in xrange(10):login_name = "test_user%i"%(i+1)real_name = join_str.join(login_name.split("_")).capitalize()create_user(login_name, real_name)uid = int(sys.stdin.readline().strip())
other_uid = int(sys.stdin.readline().strip())print "测试 follow 方法..."
print "用户 %i 关注 用户 %i"%(uid, other_uid)
f_result = follow(uid, other_uid)
print "关注结果: " + str(f_result)
print "用户 %i 的关注列表内容为: %s"%(uid, str(conn.zrange("following:%i"%(uid), 0, -1)))
print "用户 %i 的粉丝列表内容为: %s"%(other_uid, str(conn.zrange("followers:%i"%(other_uid), 0, -1)))
uid_info = conn.hgetall("user:%i"%(uid))
uid_info.pop("last_signup", "404")
other_uid_info = conn.hgetall("user:%i"%(other_uid))
other_uid_info.pop("last_signup", "404")
print "用户 %i 的用户详情为: %s"%(uid, str(uid_info))
print "用户 %i 的用户详情为: %s"%(other_uid, str(other_uid_info))
printprint "用户 %i 再次关注 用户 %i"%(uid, other_uid)
oth_f_result = follow(uid, other_uid)
print "关注结果: " + str(oth_f_result)
printprint "测试 unfollow 方法..."
print "用户 %i 取消关注 用户 %i"%(uid, other_uid)
unf_result = unfollow(uid, other_uid)
print "取消关注结果: " + str(unf_result)
print "用户 %i 的关注列表内容为: %s"%(uid, str(conn.zrange("following:%i"%(uid), 0, -1)))
print "用户 %i 的粉丝列表内容为: %s"%(other_uid, str(conn.zrange("followers:%i"%(other_uid), 0, -1)))
uid_info = conn.hgetall("user:%i"%(uid))
uid_info.pop("last_signup", "404")
other_uid_info = conn.hgetall("user:%i"%(other_uid))
other_uid_info.pop("last_signup", "404")
print "用户 %i 的用户详情为: %s"%(uid, str(uid_info))
print "用户 %i 的用户详情为: %s"%(other_uid, str(other_uid_info))
printprint "用户 %i 再次取消关注 用户 %i"%(uid, other_uid)
oth_unf_result = unfollow(uid, other_uid)
print "取消关注结果: " + str(oth_unf_result)pipe = conn.pipeline(True)
pipe.delete("users", "user:id")
keys = conn.keys("user:*") + conn.keys("followers:*") + conn.keys("following:*")
for key in keys:pipe.delete(key)
pipe.execute()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/204450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第二证券:政策稳预期强信心 民间投资结构性亮点纷呈

民营经济是中国特色社会主义商场经济的重要组成部分,是推动中国式现代化和高质量展开的生力军。本年以来,国内外环境仍然复杂多变,我国民营企业展开耐性不减。受访专家标明,跟着支撑民营经济展开的系列严峻抉择计划安置执行落地&a…

js vue 输入正确手机号/邮箱后,激活“发送验证码”按钮

按钮禁止点击状态: 按钮能够点击状态: 我采用的方式是监听手机号/邮箱输入框的输入事件,即实判断用户输入的数据是否满足规则,如果满足手机号/邮箱规则,则激活“获取验证码”按钮。 话不多说,上代码 样式…

pWnOS v2.0

该靶机绑定了静态IP地址 10.10.10.100,所以这里需要修改我们的网络配置!整个网段修改为10.10.10.0/24 信息收集 主机存活探测 arp-scan -l 端口信息探测 nmap -sT --min-rate 10000 -p- 10.10.10.100 (只开放了22 80端口) 服务…

运行时更改Android应用程序图标

设想一下,当我们正在开发一款应用。随着某个节日的临近,我们可能希望通过更改应用图标来增强用户的节日氛围,例如在图标上添“新年特惠”或者“龙年大吉”等标签。 这种小小的改变看似不经意,却能够吸引用户的注意。 运行时更改应…

Windows离线安装Node-Red

在线安装Node-Red 参考文章 步骤 安装Nodejs使用nmp安装Node-Red先在本地安装Node-red将本地的Node-red拷贝到远程 安装Nodejs 在nodejs中文网下载长期支持的Windows安装包,并进行安装 安装完成后为nodej添加环境变量,环境变量的地址为安装目录。 …

哔哩哔哩自动引流软件,其成果展示与开发流程和代码分享

先来看实操成果,↑↑需要的同学可看我名字↖↖↖↖↖,或评论888无偿分享 哔哩哔哩自动引流软件的开发流程和代码分享 一、开发背景 随着互联网的发展,越来越多的用户喜欢在哔哩哔哩平台寻找感兴趣的内容。为了更好地满足这部分用户的需求&a…

关系数据库和非关系数据库相机

目录 1、数据库介绍2、关系数据库2.1 Mysql2.2 PostgreSQL2.3 Mysql和PostgreSQL的区别 3、非关系数据库3.1 Redis3.2 MongoDB3.3 MongoDB和Redis的区别3.4 MongoDB和Mysql的区别 4、结构化数据、非结构化数据和半结构化数据5、 后端技术群 1、数据库介绍 关系数据库和非关系数…

【2023年网络安全优秀创新成果大赛专刊】医疗机构临床数据合规共享解决方案(美创科技)

“2023年网络安全优秀创新成果大赛”由中央网信办网络安全协调局指导,中国网络安全产业联盟(CCIA)主办。本次大赛由3场分站赛、3场专题赛、1场大学生创新创业作品赛组成。 在杭州分站赛,美创科技—“医疗机构临床合规共享解决方案…

Docker的数据卷、数据卷容器,容器互联

数据卷(容器与宿主机之间数据共享) 数据卷是一个供容器使用的特殊目录,位于容器中。可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,并且更新数据不会影响镜像,从而实现数据在宿主机与容器之…

借用gpt帮自己写个抓取某网站房源信息,业绩翻倍

作为一名销售不可怕,作为一个程序员不可怕,但作为一个会写代码的房产销售就很可怕了。不管是做什么都需要动脑筋,会使很多事情相对简单,这不,最近这业绩搞的自己扛不住,主要是平时很懒,都是坐等…

简单易懂:Axios 如何取消请求的两种方法

在前端开发中,网络请求是非常常见的操作。而有时候,我们可能需要在发送请求后取消它,比如用户在请求还未完成时离开了当前页面或者执行了其他操作,本文将介绍如何在使用 Axios 发送请求时取消这些请求。 基本概念 在 Axios 中&am…

Ui自动化概念 + Web自动化测试框架介绍!

1.UI自动化测试概念:我们先明确什么是UI UI,即(User Interface简称UI用户界面)是系统和用户之间进行交互和信息交换的媒介 UI自动化测试: Web自动化测试和移动自动化测试都属于UI自动化测试,UI自动化测试就是借助自动化工具对程序UI层进行自动化的测试 …

通过K8S安装人大金仓数据库

1. 离线下载镜像&#xff0c;请点击 2. 官网下载镜像 https://www.kingbase.com.cn/xzzx/index.htm&#xff0c;根据自己的需求下载对应版本。 3. K8S需要的yaml清单 cat > kingbase.yaml << EOF apiVersion: apps/v1 kind: Deployment metadata:name: kingbase-…

Django + Matplotlib:实现数据分析显示与下载为PDF或SVG

写作背景 首先&#xff0c;数据分析在当前的信息时代中扮演着重要的角色。随着数据量的增加和复杂性的提高&#xff0c;人们对于数据分析的需求也越来越高。 其次&#xff0c;笔者也确确实实曾经接到过一个这样的开发需求&#xff0c;甲方是一个医疗方面的科研团队&#xff0…

记录一下本地源码安装部署ThingsBoard可能踩到的坑

使用git下载源码后, 必须运行 mvn clean install -DskipTests这一步很重要, 有很多文件需要初始化, 如果直接放入idea可能存在各种问题, 最好是用命令行执行 初始化时, 可能报错停止, 这个一般是网络问题, 可以尝试修改maven镜像, 这是我成功构建的镜像 <!--阿里云仓库--…

Python-调试

左下角有相关的操作 断点&#xff1a;鼠标右键点击行 左下角为函数的调用栈 单步按F7

codeforces E - Good Triples

分析 易得总和总是大于等于每一位之和。如果左边的每一位之和有进位那么对于两边总和的贡献不影响&#xff0c;对于左边的位之和不影响&#xff0c;对于右边的位之和有影响。有进位相当于左边位之和加 10 10 10 &#xff0c;右边位之和加 1 1 1 。两边贡献不等&#xff0c;所…

QML与C++之间自定义对象输出

1.定义暴露的C类 Message.h #ifndef MESSAGE_H #define MESSAGE_H#include "QObject" #include "MessageAuthor.h"class Message : public QObject {Q_OBJECTQ_PROPERTY(MessageAuthor* author READ author )public:explicit Message(QObject *parent nu…

跨境电商平台投资智谋:全球化布局的策略之道

随着全球数字化浪潮的涌动&#xff0c;跨境电商平台在全球商业舞台上扮演着越来越重要的角色。其全球化布局的策略之道成为业界瞩目的焦点。 本文将深入探讨跨境电商平台投资的智谋&#xff0c;分析其全球化布局的关键策略&#xff0c;以及在这个竞争激烈的领域中脱颖而出的成…

基于若依的ruoyi-nbcio流程管理系统支持支持定时边界事件和定时捕获事件

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 1、定时边界事件 <template><div class"panel-tab__content"><!--目前只处理定…