使用Redis构建简易社交网站(1)-创建用户与动态界面

目的

本文目的:实现简易社交网站中创建新用户和创建新动态功能。(完整代码附在文章末尾)

相关知识

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

redis基本命令

hget:从哈希中获取指定域的值。

conn = redis.Redis()
conn.hget("testhash", "field1")

执行结果:2

incr:将 key 中储存的数字值增一。

conn = redis.Redis()
conn.incr("testcount")

执行前:不存在 testcount 键。

执行后:

testcount 1

hset:将哈希中域 field 的值设为 value

conn = redis.Redis()
conn.hset("testhash", "field1", 2)
conn.hset("testhash", "field2", 4)

执行前:

{'field1': '1'}

执行后:

{'field1': '2', 'field2': '4'}

hmset:同时将多个域-值对设置到哈希表中。

conn = redis.Redis()
conn.hmset("test_hash", {
'id': 1,
'name': 'educoder',
'age': 2,
})

执行后:

{'age': '2', 'id': '1', 'name': 'educoder'}

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

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

执行前:

{'field1': '1'}

执行后:

{'field1': '2'}

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基本命令

将字符串全小写化:

'Hello, Educoder'.lower()

执行结果:'hello, educoder'

返回当前时间的时间戳。

time.time()

使用格式化拼接字符串:

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

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

实战例题:

编写 create_user(login_name, real_name) 函数,实现创建新用户的功能,具体参数与要求如下:

  • 方法参数login_name为用户登录名,real_name为用户真名;
  • 用户登录名预处理的实现:将用户登录名转换成全小写格式;
  • 重名检测的实现:查询哈希键users中是否存在与用户登录名同名的域,若存在,则不允许重新创建该用户,返回None
  • 分配用户编号的实现:对计数器user:id递增1,并将递增后的值作为新用户的编号;
  • 存储用户信息的实现:使用事务一次性提交:
    • 存储登录名的实现:将用户登录名记录到哈希键users当中,值为该用户编号;
    • 存储详情的实现:按照如下示意将用户信息存储到哈希键user:{id}中:

  • 返回创建结果的实现:返回新创建用户的编号。

编写 create_post(uid, content) 函数,实现创建新动态的功能,具体参数与要求如下:

  • 方法参数uid为发布动态的用户编号,content为要发布的动态内容;
  • 用户合法性检测的实现:查找用户编号对应详情信息哈希user:{uid}是否存在login_name域,若存在,则记录,若不存在,则不允许创建新动态,返回None
  • 分配动态编号的实现:对计数器post:id递增1,并将递增后的值作为新动态的编号;
  • 存储动态信息的实现:按照如下示意将动态信息存储到哈希键post:{id}中:

  • 更新用户动态数的实现:为该用户编号对应的详情信息哈希user:{uid}中的posts域的值加1
  • 返回创建结果的实现:返回新创建动态的编号。

 code.py

#code.py
#-*- coding:utf-8 -*-import re
import time
import redisconn = redis.Redis()# 创建新用户
def create_user(login_name, real_name):# 请在下面完成要求的功能#********* Begin *********#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#********* End *********## 为用户创建新动态
def create_post(uid, content):# 请在下面完成要求的功能#********* Begin *********#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#********* End *********#

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", "post:id")
keys = conn.keys("user:*") + conn.keys("post:*")
for key in keys:pipe.delete(key)
pipe.execute()print "测试 create_user 方法..."
print "第一次创建登录名为 TestUser 的用户"
result1 = create_user('TestUser', 'Test User')
print "创建的用户ID为: " + str(result1)
print "当前分配的用户ID为: " + conn.get("user:id")
user_info = conn.hgetall("user:%i"%(result1))
user_info.pop("last_signup", "404")
print "创建的用户信息为: " + str(user_info)
printprint "第二次创建登录名为 TestUser 的用户"
result2 = create_user('TestUser', 'Test User2')
print "创建的用户ID为: " + str(result2)
print "当前分配的用户ID为: " + conn.get("user:id")
printprint "测试 create_post 方法..."
print "为用户 1 创建一条动态"
pid = create_post(1, "First POST!")
print "创建的动态ID为: " + str(pid)
print "当前分配的动态ID为: " + conn.get("post:id")
post_info = conn.hgetall("post:%i"%(pid))
post_info.pop("posted", "404")
print "创建的动态信息为: " + str(post_info)
user_info = conn.hgetall("user:1")
user_info.pop("last_signup", "404")
print "对应用户信息中更新为: " + str(user_info)
printprint "为不存在的用户 9 创建一条动态"
pid2 = create_post(9, "Illegal POST!")
print "创建的动态ID为: " + str(pid2)pipe.delete("users", "user:id", "post:id")
keys = conn.keys("user:*") + conn.keys("post:*")
for key in keys:pipe.delete(key)
pipe.execute()

测试输入:无;

预期输出:

测试 create_user 方法...
第一次创建登录名为 TestUser 的用户
创建的用户ID为: 1
当前分配的用户ID为: 1
创建的用户信息为: {'login_name': 'testuser', 'posts': '0', 'real_name': 'Test User', 'followers': '0', 'following': '0', 'id': '1'}第二次创建登录名为 TestUser 的用户
创建的用户ID为: None
当前分配的用户ID为: 1测试 create_post 方法...
为用户 1 创建一条动态
创建的动态ID为: 1
当前分配的动态ID为: 1
创建的动态信息为: {'content': 'First POST!', 'uid': '1', 'user_name': 'testuser', 'id': '1'}
对应用户信息中更新为: {'login_name': 'testuser', 'posts': '1', 'real_name': 'Test User', 'followers': '0', 'following': '0', 'id': '1'}为不存在的用户 9 创建一条动态
创建的动态ID为: None

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

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

相关文章

java后端技术演变杂谈(未完结)

1.0版本javaWeb:原始servletjspjsbc 早期的jsp:htmljava,页面先在后端被解析,里面的java代码动态渲染完成后,成为纯html,再通过服务器发送给浏览器显示。 缺点: 服务器压力很大,因为…

python提取通话记录中的时间信息

您需要安装适合中文的SpaCy模型。您可以通过运行 pip install spacypython -m spacy download zh_core_web_sm来安装和下载所需的模型。 import spacy# 加载中文模型 nlp spacy.load(zh_core_web_sm)# 示例电话记录文本 text """ Agent: 今天我们解决一下这…

QT之QString

QT之QString 添加容器 点击栅格布局 添加容器,进行栅格布局 布局总结:每一个模块放在一个Group中,排放完之后,进行栅格布局。多个Group进行并排时,先将各个模块进行栅格布局,然后都选中进行垂直布…

华清远见嵌入式学习——C++——作业3

作业要求&#xff1a; 代码&#xff1a; #include <iostream>using namespace std;class Per { private:string name;int age;double *high;double *weight; public://有参构造函数Per(string n,int a,double h,double w):name(n),age(a),high(new double(h)),weight(ne…

14 网关实战:网关聚合API文档

上节课介绍了网关层的认证鉴权,今天这节介绍一下网关层如何聚合API接口文文档。 为什么需要聚合API接口文档? 大型微服务系统模块众多,木谷博客系统就有9个,如果这些服务的接口地址没有一个统一,那么客户端将要保存每个服务的接口地址,这个肯定是不现实。 先来看一下A…

11. 哈希冲突

上一节提到&#xff0c;通常情况下哈希函数的输入空间远大于输出空间&#xff0c;因此理论上哈希冲突是不可避免的。比如&#xff0c;输入空间为全体整数&#xff0c;输出空间为数组容量大小&#xff0c;则必然有多个整数映射至同一桶索引。 哈希冲突会导致查询结果错误&#…

机器学习的复习笔记3-回归的细谈

一、回归的细分 机器学习中的回归问题是一种用于预测连续型输出变量的任务。回归问题的类型和特点如下&#xff1a; 线性回归&#xff08;Linear Regression&#xff09;&#xff1a;线性回归是回归问题中最简单的一种方法。它假设自变量与因变量之间存在线性关系&#xff0c…

【Unity动画】状态机添加参数控制动画切换(Animator Controller)

Unity - 手册&#xff1a;动画参数 在Unity中&#xff0c;动画状态的切换是通过Animator Controller中的过渡&#xff08;Transition&#xff09;来实现的。过渡是状态之间的连接&#xff0c;控制过渡一般都是靠调用代码参数 我们来实现一个案例&#xff1a; 创建动画状态机&a…

vscode中使用luaide-lite插件断点调试cocos2dx-lua

使用quick-cocos2dx-lua&#xff0c;用了众多插件&#xff0c;包括免费的BabeLua,VS调试太慢&#xff0c;vscode上的免费的EmmyLua, 还有收费的luaide&#xff0c;都没搞出来&#xff0c;唯独这个免费luaide-lite用成功了&#xff0c;步骤也简单&#xff0c;可以断点调试&#…

数据结构第六课 -----链式二叉树的实现

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

Java SpringBoot Controller常见写法

文章目录 环境Controller调用脚本运行结果总结 环境 系统: windows 11 工具: java, idea, git bash Controller 接口常见有以下几种方式 其中&#xff1a; Tobj 调用脚本 我的是windows 系统&#xff0c;使用 git bash 窗口运行, 用 cmd 或者 power shell 会有问题 curl …

C盘分析文件大小的软件

https://sourceforge.net/projects/windirstat/ 上面是windirstat的下载链接 界面是这样的&#xff1a; 选择C盘或者D盘&#xff0c;点击OK&#xff0c;就可以分析了 然后就可以看到哪些占比最高&#xff0c;可以针对性的清理

C#网络编程UDP程序设计(UdpClient类)

目录 一、UdpClient类 二、示例 1.源码 &#xff08;1&#xff09;Client &#xff08;2&#xff09;Server 2.生成 &#xff08;1&#xff09;先启动服务器&#xff0c;发送广播信息 &#xff08;2&#xff09;再开启客户端接听 UDP是user datagram protocol的简称&a…

整数的立方和

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

bad_python

攻防世界 (xctf.org.cn) 前戏 下载文件&#xff0c;解压完成后是这个 一个pyc文件 这里要用到python的反编译 要用到的工具有两个 1.python自带的uncompyle6 2.pycdc文件——比uncompyle6强大一点 我们一个一个来尝试一下 uncompyle6&#xff1a; 我是直接在pycharm里面…

uniapp在H5端实现PDF和视频的上传、预览、下载

上传 上传页面 <u-form-item :label"(form.ququ3 1 ? 参培 : form.ququ3 2 ? 授课 : ) 证明材料" prop"ququ6" required><u-button click"upload" slot"right" type"primary" icon"arrow-upward" t…

设计模式-结构型模式之代理设计模式

文章目录 八、代理设计模式 八、代理设计模式 代理设计模式通过代理控制对象的访问&#xff0c;可以详细访问某个对象的方法&#xff0c;在这个方法调用处理&#xff0c;或调用后处理。既(AOP微实现) 。 代理有分静态代理和动态代理&#xff1a; 静态代理&#xff1a;在程序…

集成开发环境PyCharm的使用【侯小啾python基础领航计划 系列(三)】

集成开发环境 PyCharm 的使用【侯小啾python基础领航计划 系列(三)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹…

QT 中 QProgressDialog 进度条窗口 备查

基础API //两个构造函数 QProgressDialog::QProgressDialog(QWidget *parent nullptr, Qt::WindowFlags f Qt::WindowFlags());QProgressDialog::QProgressDialog(const QString &labelText, const QString &cancelButtonText, int minimum, int maximum, QWidget *…

BFS求树的宽度——结合数组建树思想算距离

二叉树最大宽度 https://leetcode.cn/problems/maximum-width-of-binary-tree/description/ 1、考虑树的宽度一定是在一层上的所以进行BFS&#xff0c;树的BFS不建议直接使用队列&#xff0c;每次add/offer然后poll/remove&#xff0c;这样子层级关系不好显示。我们可以定义…