本文主要是介绍2021-07-28 前端登录注册功能 redis的安装和使用 redis字符串类型 字典类型 列表类型 通用操作 管道 django使用redis,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
昨日回顾
1 验证手机号是否存在接口
2 使用腾讯云发送短信
-api,sdk
-两个 :3版本和2版本
-3版本不仅仅有发送短信,腾讯云的其他服务,都集成进去了
-2版本只有发送短信功能
-二次封装:更简单的使用腾讯云sdk发送短信
-发送短信接口
-缓存验证码
-短信发送的同步和异步
3 短信登录接口
-前端传递过来:手机号和验证码
-把验证码取出来,校验验证码是否正确
-根据手机号查到用户,签发token,返回
4 短信注册接口
-前端传递:手机号,验证码,密码
-校验验证码是否正确
-重写create方法:User.object.create_user()
5 发送短信频率限制
今日内容
1 前端登录,注册功能
1.1 Login.vue
<template>
<div class="login">
<div class="box">
<i class="el-icon-close" @click="close_login"></i>
<div class="content">
<div class="nav">
<span :class="{active: login_method === 'is_pwd'}"
@click="change_login_method('is_pwd')">密码登录</span>
<span :class="{active: login_method === 'is_sms'}"
@click="change_login_method('is_sms')">短信登录</span>
</div>
<el-form v-if="login_method === 'is_pwd'">
<el-input
placeholder="用户名/手机号/邮箱"
prefix-icon="el-icon-user"
v-model="username"
clearable>
</el-input>
<el-input
placeholder="密码"
prefix-icon="el-icon-key"
v-model="password"
clearable
show-password>
</el-input>
<el-button type="primary" @click="login_pwd">登录</el-button>
</el-form>
<el-form v-if="login_method === 'is_sms'">
<el-input
placeholder="手机号"
prefix-icon="el-icon-phone-outline"
v-model="mobile"
clearable
@blur="check_mobile">
</el-input>
<el-input
placeholder="验证码"
prefix-icon="el-icon-chat-line-round"
v-model="sms"
clearable>
<template slot="append">
<span class="sms" @click="send_sms">{{ sms_interval }}</span>
</template>
</el-input>
<el-button type="primary" @click="sms_login">登录</el-button>
</el-form>
<div class="foot">
<span @click="go_register">立即注册</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
username: '',
password: '',
mobile: '',
sms: '',
login_method: 'is_pwd',
sms_interval: '获取验证码',
is_send: false,
}
},
methods: {
close_login() {
this.$emit('close')
},
go_register() {
this.$emit('go')
},
change_login_method(method) {
this.login_method = method;
},
check_mobile() {
if (!this.mobile) return;
if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
this.$message({
message: '手机号有误',
type: 'warning',
duration: 1000,
onClose: () => {
this.mobile = '';
this.is_send = false;
}
});
return false;
}
//调用后端手机号是否存在接口,判断
this.$http.get(this.$settings.base_url + '/api/user/check_mobile/?mobile=' + this.mobile).then(res => {
if (res.data.code == 100 && res.data.exisit) {
// this.$message()
this.is_send = true;
} else {
this.$message('该手机号未注册,请先去注册')
this.$emit('go')
}
})
},
send_sms() {
if (!this.is_send) return;
this.is_send = false;
let sms_interval_time = 60;
this.sms_interval = "发送中...";
let timer = setInterval(() => {
if (sms_interval_time <= 1) {
clearInterval(timer);
this.sms_interval = "获取验证码";
this.is_send = true; // 重新回复点击发送功能的条件
} else {
sms_interval_time -= 1;
this.sms_interval = `${sms_interval_time}秒后再发`;
}
}, 1000);
// 发送请求,获取验证码
this.$http.get(this.$settings.base_url + '/api/user/send_sms/?mobile=' + this.mobile).then(res => {
this.$message(res.data.msg)
})
},
login_pwd() {
if (this.username && this.password) {
this.$http.post(this.$settings.base_url + '/api/user/login/', {
username: this.username,
password: this.password
}).then(res => {
if (res.data.code == 100) {
// 把用户名和token放到cookie中(s:秒,d:天,m:月)
this.$cookie.set('token', res.data.token, '7d')
this.$cookie.set('username', res.data.username, '7d')
//关闭登录框
this.$emit('close')
} else {
this.$message({
message: res.data.msg[0],
type: 'error'
})
}
})
} else {
this.$message({
message: '用户名或密码没有填',
type: 'warning'
})
}
},
sms_login(){
if (this.mobile && this.sms) {
this.$http.post(this.$settings.base_url + '/api/user/mobile_login/', {
mobile: this.mobile,
code: this.sms
}).then(res => {
if (res.data.code == 100) {
// 把用户名和token放到cookie中(s:秒,d:天,m:月)
this.$cookie.set('token', res.data.token, '7d')
this.$cookie.set('username', res.data.username, '7d')
//关闭登录框
this.$emit('close')
} else {
this.$message({
message: res.data.msg[0],
type: 'error'
})
}
})
} else {
this.$message({
message: '手机号或验证码没有填',
type: 'warning'
})
}
},
}
}
</script>
<style scoped>
.login {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
}
.box {
width: 400px;
height: 420px;
background-color: white;
border-radius: 10px;
position: relative;
top: calc(50vh - 210px);
left: calc(50vw - 200px);
}
.el-icon-close {
position: absolute;
font-weight: bold;
font-size: 20px;
top: 10px;
right: 10px;
cursor: pointer;
}
.el-icon-close:hover {
color: darkred;
}
.content {
position: absolute;
top: 40px;
width: 280px;
left: 60px;
}
.nav {
font-size: 20px;
height: 38px;
border-bottom: 2px solid darkgrey;
}
.nav > span {
margin: 0 20px 0 35px;
color: darkgrey;
user-select: none;
cursor: pointer;
padding-bottom: 10px;
border-bottom: 2px solid darkgrey;
}
.nav > span.active {
color: black;
border-bottom: 3px solid black;
padding-bottom: 9px;
}
.el-input, .el-button {
margin-top: 40px;
}
.el-button {
width: 100%;
font-size: 18px;
}
.foot > span {
float: right;
margin-top: 20px;
color: orange;
cursor: pointer;
}
.sms {
color: orange;
cursor: pointer;
display: inline-block;
width: 70px;
text-align: center;
user-select: none;
}
</style>
1.2 Register.vue
<template>
<div class="register">
<div class="box">
<i class="el-icon-close" @click="close_register"></i>
<div class="content">
<div class="nav">
<span class="active">新用户注册</span>
</div>
<el-form>
<el-input
placeholder="手机号"
prefix-icon="el-icon-phone-outline"
v-model="mobile"
clearable
@blur="check_mobile">
</el-input>
<el-input
placeholder="密码"
prefix-icon="el-icon-key"
v-model="password"
clearable
show-password>
</el-input>
<el-input
placeholder="验证码"
prefix-icon="el-icon-chat-line-round"
v-model="sms"
clearable>
<template slot="append">
<span class="sms" @click="send_sms">{{ sms_interval }}</span>
</template>
</el-input>
<el-button type="primary" @click="register">注册</el-button>
</el-form>
<div class="foot">
<span @click="go_login">立即登录</span>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "Register",
data() {
return {
mobile: '',
password: '',
sms: '',
sms_interval: '获取验证码',
is_send: false,
}
},
methods: {
close_register() {
this.$emit('close', false)
},
go_login() {
this.$emit('go')
},
check_mobile() {
if (!this.mobile) return;
if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
this.$message({
message: '手机号有误',
type: 'warning',
duration: 1000,
onClose: () => {
this.mobile = '';
}
});
return false;
}
//校验手机号是否注册过,如果注册过,就不能再发短信了
this.$http.get(this.$settings.base_url + '/api/user/check_mobile/?mobile=' + this.mobile).then(res => {
if (res.data.code == 100 && res.data.exisit) {
this.$message('该手机号已经注册,请先去直接登录')
// this.mobile=''
this.$emit('go')
} else {
this.is_send = true;
}
})
},
send_sms() {
if (!this.is_send) return;
this.is_send = false;
let sms_interval_time = 60;
this.sms_interval = "发送中...";
let timer = setInterval(() => {
if (sms_interval_time <= 1) {
clearInterval(timer);
this.sms_interval = "获取验证码";
this.is_send = true; // 重新回复点击发送功能的条件
} else {
sms_interval_time -= 1;
this.sms_interval = `${sms_interval_time}秒后再发`;
}
}, 1000);
// 发送请求,获取验证码
this.$http.get(this.$settings.base_url + '/api/user/send_sms/?mobile=' + this.mobile).then(res => {
this.$message(res.data.msg)
})
},
register(){
if (this.mobile && this.sms && this.password) {
this.$http.post(this.$settings.base_url + '/api/user/register/', {
mobile: this.mobile,
code: this.sms,
password:this.password
}).then(res => {
if (res.data.code == 100) {
//跳转到登录页面
this.$emit('go')
} else {
this.$message({
message: res.data.msg[0],
type: 'error'
})
}
})
} else {
this.$message({
message: '手机号或验证码没有填',
type: 'warning'
})
}
}
}
}
</script>
<style scoped>
.register {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: 10;
background-color: rgba(0, 0, 0, 0.3);
}
.box {
width: 400px;
height: 480px;
background-color: white;
border-radius: 10px;
position: relative;
top: calc(50vh - 240px);
left: calc(50vw - 200px);
}
.el-icon-close {
position: absolute;
font-weight: bold;
font-size: 20px;
top: 10px;
right: 10px;
cursor: pointer;
}
.el-icon-close:hover {
color: darkred;
}
.content {
position: absolute;
top: 40px;
width: 280px;
left: 60px;
}
.nav {
font-size: 20px;
height: 38px;
border-bottom: 2px solid darkgrey;
}
.nav > span {
margin-left: 90px;
color: darkgrey;
user-select: none;
cursor: pointer;
padding-bottom: 10px;
border-bottom: 2px solid darkgrey;
}
.nav > span.active {
color: black;
border-bottom: 3px solid black;
padding-bottom: 9px;
}
.el-input, .el-button {
margin-top: 40px;
}
.el-button {
width: 100%;
font-size: 18px;
}
.foot > span {
float: right;
margin-top: 20px;
color: orange;
cursor: pointer;
}
.sms {
color: orange;
cursor: pointer;
display: inline-block;
width: 70px;
text-align: center;
user-select: none;
}
</style>
2 redis介绍和安装
# https://www.cnblogs.com/liuqingzheng/articles/9833534.html
# redis:是一个key-value存储系统,非关系型数据库(nosql数据库),数据存在于内存中,缓存数据库
# redis支持5大数据类型:字符串,列表,hash(字典),集合,有序集合
# 使用Redis有哪些好处
-速度快:缓存数据库
-支持丰富数据类型:5大数据类型
-支持事务:通过管道支持(单实例上有效)
-丰富的特性:可用于缓存,消息队列,按key设置过期时间,过期后将会自动删除
# redis相比memcached有哪些优势
-都是内存数据库
-redis类型丰富,5大类型,memcached只支持字符串类型
-redis支持持久化,memcached不支持持久化
-redis速度比mencached快
# 特点
可以持久化
单线程,单进程
-redis最新版本是6.x
-6.x之前是单线程,单进程
# redis单线程为什么这么快?并发量:10w,6w左右
-1 纯内存操作
-2 使用了io多路复用模型(epoll select)
-3 因为是单线程,不存在线程间切换,节省资源
# 服务:客户端,服务端(跟mysql一样, 是存数据的地方)
# 安装:
-redis使用c语言写的,开源,,我们不支持windows,第三方,基于redis源码,自行修改,编译成windows平台可以运行的(win平台:维护到 3.x版本),咱们现在讲,以3.x为例
# 官网
http://redis.cn/
-官网提供了c源码,需要自行下载,编译
-win平台,自己找一个安装包(不是官方提供的)https://github.com/microsoftarchive/redis
-Redis-x64-3.2.100.msi:一路下一步
-图形化界面的客户端:redis-desktop-manager:一开始免费,后来收费了:一路下一步
-监听端口默认是:6379
# 启动redis服务
-第一种:在任意路径下敲:redis-server # 等同于mysqld
-第二种:win平台,已经做成了服务,把服务启动即可
-"D:\Program Files\Redis\redis-server.exe" --service-run "D:\Program Files\Redis\redis.windows-service.conf"
# 客户端连接
-第一种方式:在任意路径下敲:redis-cli -h 127.0.0.1 -p 6379 # 等同于 mysql -h -P
-如果连本地的6379端口,直接敲redis-cli
-使用客户端连接
-使用python操作:pip3 install redis
1.2 普通连接和连接池
# from redis import Redis
### 普通连接
# 拿到一个redis连接
# conn=Redis(host='127.0.0.1',port=6380)
# # conn=Redis()
#
# # 操作redis
# conn.set('name','lqz')
#
# conn.close()
###redis连接池
# import redis
#
# #拿到一个连接数为3的连接池
# # 把POOL做成单例:把它以模块导入方式
# POOL=redis.ConnectionPool(max_connections=3,host='127.0.0.1', port=6380)
# # 从连接池中拿出一个连接,给conn
# conn=redis.Redis(connection_pool=POOL)
#
# conn.set('age',19)
# conn.close() # 不是关闭连接,把该连接,放回到连接池
#####把POOL以单例形式使用
import redis
from pool import POOL # 以模块形式导入,是天然单例
conn=redis.Redis(connection_pool=POOL)
# conn2=redis.Redis(connection_pool=POOL)
# conn3=redis.Redis(connection_pool=POOL)
# conn4=redis.Redis(connection_pool=POOL)
# conn5=redis.Redis(connection_pool=POOL)
# conn6=redis.Redis(connection_pool=POOL)
conn.set('age',19)
conn.close() # 不是关闭连接,把该连接,放回到连接池
import redis
#拿到一个连接数为3的连接池
# 把POOL做成单例:把它以模块导入方式
POOL=redis.ConnectionPool(max_connections=3,host='127.0.0.1', port=6380)
3 redis 5大数据类型之字符串
'''
set(name, value, ex=None, px=None, nx=False, xx=False) 重点
setnx(name, value)
setex(name, value, time)
psetex(name, time_ms, value)
mset(*args, **kwargs) 重点
get(name) 重点
mget(keys, *args) 重点
getset(name, value)
getrange(key, start, end)
setrange(name, offset, value)
setbit(name, offset, value)
getbit(name, offset)
bitcount(key, start=None, end=None)
strlen(name) 重点
incr(self, name, amount=1) 重点
incrbyfloat(self, name, amount=1.0)
decr(self, name, amount=1)
append(key, value)
'''
import redis
conn=redis.Redis()
# set:放字符串值
'''
ex,过期时间(秒)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行,值存在,就修改不了,执行没效果
xx,如果设置为True,则只有name存在时,当前set操作才执行,值存在才能修改,值不存在,不会设置新值
'''
# conn.set('name','lqz')
# res=conn.set('name','lqz',ex=3)
# res=conn.set('name','lqz',px=3000)
# res=conn.set('name','lqz')
# res=conn.set('name','egon')
# res=conn.set('name','lqz',nx=True)
# res=conn.set('name','19',xx=True)
# get 获取值
# res=conn.get('name')
# mset 批量设置值
# conn.mset({'name':'lqz','age':19,'sex':'男'})
# mget 批量获取值
# res=conn.mget(['name','age'])
# res=conn.mget('name','age')
# conn.setex(name, value, time)
# conn.psetex(name, time_ms, value)
# conn.set(name, valeu, px=time)
# res=conn.getset('name', '刘亦菲')
# res=conn.getrange('name',3,5) #前闭后闭区间 拿到 亦 这个字 拿字节
#
# print(str(res,encoding='utf-8'))
# res=conn.setrange('name',0,'lqzzzzzzz')
# res=conn.setrange('name',0,'qq')
##获取和设置比特位
# setbit(name, offset, value)
# getbit(name, offset)
# print(conn.getbit('name',3))
# conn.setbit('name',0,1)
# print(conn.getbit('name',0))
# print(conn.strlen('name')) # 指的是字节 获取字节长度
# conn.incr('age') # 让该键自增1
# conn.incrby('age',3) # 让该键自增3
# conn.incrbyfloat('age', amount=1.1)
conn.append('name', 'nb')
conn.close()
4 redis 5大数据类型之Hash
5 redis 5大数据类型之列表
6 其他操作
7 管道
8 django使用redis
# 第一种:通用方式(任何web框架都可以)
# 第二种:django提供的
-在配置文件中配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100} # 连接池大小为100
# "PASSWORD": "123",
}
}
}
-安装django_redis模块
-使用
from django_redis import get_redis_connection
def index(request):
conn=get_redis_connection()
res=conn.get('name')
print(res)
return HttpResponse('okkkkk')
-一旦这样配置,django中的缓存,也用redis
cache.set('key',python的任意对象)
这篇关于2021-07-28 前端登录注册功能 redis的安装和使用 redis字符串类型 字典类型 列表类型 通用操作 管道 django使用redis的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!