注册页面的功能的思维逻辑(逻辑图)
配置准备项目
命令:
后端
- 在指定的文件下进行cmd进入小黑框创建项目
- 创建的项目的命令 django-admin startproject 项目名
- 然后拉入pythoncharm进行编写
- 进入后创建子应用 python manage.py startapp 子应用名
- 产生迁移文件 python manage.py makemigrations
- 生成迁移 python manage.py migrate
- 运行项目 python manage.py runserver
前端
- npm run serve 项目的运行
- npm run dev 项目的运行
- npm run 查看项目运用什么进行程序的执行
setting文件下的配置
配置子应用,drf框架,跨域,
INSTALLED_APPS = [
'users',# 配置子组件
'corsheaders',# 注册跨域
'rest_framework',# 注册drf框架
]
配置中间件
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 配置中间件
]
配置先关的配置定制(ip白名单,允许cookie,允许请求方式,配置允许请求痛头部)
# 配置跨域相关配置订制
CORS_ORIGIN_WHITELIST=[ # 配置ip白名单
'http://127.0.0.1:8080', # 8080这个根据前端进行修改
'http://localhost:8080'
]
CORS_ALLOW_CREDENTIALS=True #配置允许cookie
CORS_ALLOW_METHODS=('*') # 配置允许请求方式
CORS_ALLOW_HEADERS=('*') # 配置允许的请求头
配置数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST':'localhost', # 主机
'PORT':3306, # 路由
'USER':'xxx', # 数据库名
'PASSWORD':'xxx', # 密码
'NAME':'redmi' # 数据库名
}
}
配置验证码的图片
# 配置文件夹
STATICFILES_DIRS=(
os.path.join(BASE_DIR,'static'), # 逗号不能少
)
同名文件下的init文件下进行安装数据库操作
import pymysql
pymysql.install_as_MySQLdb()
配置模型类
from django.db import models
# Create your models here.
# 用户模型
class User(models.Model): # CharField 字符串类型 unique 唯一 True 允许唯一
user_name=models.CharField(max_length=20,verbose_name='用户名',unique=True)
password=models.IntegerField('密码',max_length=10)
mobile=models.CharField('手机号',max_length=16) # 手机号
class Meta:
verbose_name='用户表' #admin上的名字
verbose_name_plural=verbose_name # 去除在admin页面上的s复数
db_table='user'
def __str__(self):
return '%s (%s)' % (self.user_name,self.mobile)
路由分发
主路由:
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('user/',include('users.urls')),
path('goods/',include('goods.urls')),
]
子路由:
from django.urls import path
from users import views
urlpatterns = [
]
注:准备成功-------------------------执行下面的视图操作
编写视图view
导包:
from django.shortcuts import render
from users.models import User,IndexImage
# Create your views here.
from rest_framework.response import Response
from rest_framework.views import APIView
from django.http import HttpResponse
import random
import re,code
1.功能一(判断用户名)后端
class CheckUserNameView(APIView):
def get(self,request,user_name):
# 判断用户名是否输入,没有输入 username=''
# 检测用户名长度 检测用户名是否存在
if not user_name:
return Response({
"code": 400,
"msg": "用户名不匹配"
})
if not (6<=len(user_name)<=20):
return Response('用户长度不符合')
# 程序走到这步,代表username里面一定包含
username_count = User.objects.filter(user_name=user_name).count()
if username_count:
return Response({
"code": 400,
"msg": "用户名已存在"
})
return Response({
"code": 200,
"msg": "用户名输入成功"
})
***配置动态路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/users/<str:user_name>/',views.CheckUserNameView.as_view()), # 用户名路由
]
前端:
// 失败 return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
// 成功 return callback();
let url='/user/check/users/' +value +'/'; # 动态路由要配置值
this.$axios.get(url).then((resp) => { # 和后端采用同一个方法
if (resp.data.code==200){ # 如果状态码为200 返回成功
return callback(); # callback(); 前端项目返回的自带的
}
else{ # 否则则返回错误 前端自带格式
return callback(new Error(resp.data.msg))
}
}).catch((err) => {
console.log(err)
alert('报错')
});
功能二 手机号码匹配
后端:
class CheckMobileView(APIView):
def get(self,request,mobile):
rule=r'^1[3-9][0-9]{9}$'
rs=re.findall(rule,mobile)
if not rs:
return Response({
"code":400,
"msg":"手机号不匹配"
})
mobile_count=User.objects.filter(mobile=mobile).count()
if mobile_count:
return Response({
"code":400,
"msg":"手机号已存在"
})
return Response({
"code":200,
"msg":"手机号输入成功"
})
------------------------------------------------------------------------- -
***路由动态路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/mobile/<str:mobile>/',views.CheckMobileView.as_view()), # 用户名路由
]
前端:
// 手机号的校验方法
let validateMobile = (rule, value, callback) => {
console.log("校验手机号,规则", rule, "手机号", value, "回调函数", callback)
// TODO 校验手机号
// 失败 return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
// 成功 return callback();
---------------------------------------------------------------------------------------
let url='/user/check/mobile/' + value +'/'; # 获取后端传过来的接口
this.$axios.get(url).then((resp) => { # 采用get方法
if (resp.data.code==200){ # 成功执行状态码200
return callback();
}else{
return callback(new Error(resp.data.msg))
}
}).catch((err) => {
console.log(err)
alert('报错')
});
功能三 实现密码的输入判断(检测)
后端:
class CheckPasswordView(APIView):
def post(self,request):
pwd=request.data.get('pwd')
if not (6<=len(pwd)<=10):
return Response({
"code": 400,
"msg":'密码长度不符合'
})
return Response({
"code": 200,
"msg":f'密码匹配到了{pwd}'
})
-----------------------------------------------------------------------
***路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/password/',views.CheckPasswordView.as_view()),
]
前端:
// 手机号的校验方法
let validateMobile = (rule, value, callback) => {
console.log("校验手机号,规则", rule, "手机号", value, "回调函数", callback)
// TODO 校验手机号
// 失败 return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
// 成功 return callback();
let url='/user/check/mobile/' + value +'/';
this.$axios.get(url).then((resp) => {
if (resp.data.code==200){
return callback();
}else{
return callback(new Error(resp.data.msg))
}
}).catch((err) => {
console.log(err)
alert('报错')
});
if(!value){
return
}
};
// 密码的校验方法
let validatePass = (rule, value, callback) => {
console.log("校验密码,规则", rule, "密码", value, "回调函数", callback)
// TODO 校验密码
// 失败 return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
// 成功 return callback();
***********************************************************************************
this.$axios.post('/user/check/password/',{'pwd':value}).then((resp) => {
if (resp.data.code==200){
return callback();
}else{
return callback(new Error(resp.data.msg))
}
}).catch((err) => {
console.log(err)
alert('报错')
});
功能四 密码的检验(确认密码)
后端:
class CheckPasswordReView(APIView):
def post(self,request):
pwd=request.data.get('pwd') # 密码
pwd_re=request.data.get('pwd_re') # 再次输入密码
if pwd !=pwd_re:
return Response({
"code":400,
"msg":'密码不一致'
})
else:
return Response({
"code": 200,
"msg":f'密码一致'
})
----------------------------------------------------------------------------------------
***静态路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/password_re/',views.CheckPasswordReView.as_view()),
]
前端:
// 确认密码的校验方法
let validateConfirmPass = (rule, value, callback) => {
console.log("校验确认密码,规则", rule, "二次输入的密码", value, "回调函数", callback)
// TODO 校验确认密码
// 失败 return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
// 成功 return callback();
********************************************************************************
this.$axios.post('/user/check/password_re/',{
'pwd':this.RegisterUser.pass,
'pwd_re':value
}).then((resp) => {
if (resp.data.code==200){
return callback();
}else{
return callback(new Error(resp.data.msg))
}
}).catch((err) => {
console.log(err)
alert('报错')
});
if(!value){
return
}
};
功能五 验证码生成的图片
后端:
需要导入的命令和包:
需要安装的库 pip install captcha
import random # 随机数包
class VerImge(APIView):
def get(self,request,uuid): uuid为传过来的参数
# 生成验证码所需要的字符串 randint是随机数
cont= str(random.randint(1000,9999)) 将随机生成的4位数的随机数转化为字符串
# 变成图片***/
from captcha.image import ImageCaptcha # 使用这个库这个需要安装库
img=ImageCaptcha() # 实例化验证码图片
img_pic=img.generate(cont) # 生成验证码的图片
print('生成的图片',img_pic) # 返回是一个id字节
# 把验证码存到redis
import redis
r=redis.Redis(host='127.0.0.1',port=6379,db=1)
r.set(uuid,cont,ex=60*5)
return HttpResponse(img_pic, content_type="image/png")
------------------------------------------------------------------------------------------
***传参数路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/imge/<str:uuid>/',views.VerImge.as_view()),# 生成验证码图像
]
前端:
// 校验图片验证码
let validateImageCode = (rule, value, callback) => {
console.log("校验验证码,规则", rule, "二验证码", value, "回调函数", callback)
// TODO 校验验证码
// 失败 return callback(new Error("字母开头,长度5-16之间,允许字母数字下划线"));
// 成功 return callback();
********************************************************************************
this.$axios.post('/user/check/image/code/',{
'uuid':this.imageCodeID,
'code':value
}).then((resp) => {
if(resp.data.code==200){
return callback();
}else{
return callback(new Error(resp.data.msg));
}
}).catch((err) => {
console.log(err);
alert('页面报错')
});
功能六 校验验证码
后端:
class VerImage(APIView):
def post(self,request):
code =request.data.get('code') # 用户输入的验证码
uuid=request.data.get('uuid') # 用户的唯一标志
print(uuid)
# 1.连接数据库 去除uuid对应的验证码
import redis
r=redis.Redis(host='127.0.0.1',db=1)
sys_code=r.get(uuid)# get 为取出的意思数据库的数据
print(sys_code)
# 如果uuid为空的话 验证码已过期
if not sys_code:
return Response({
"code": 400,
"msg": '验证码过期'
})
sys_code_str=sys_code.decode() # .decode()转换成字符串的意思
#2.用用户输入的验证码和数据库的验证码进行比对
if sys_code_str != code:
# 3.如果不一致报错
return Response({
"code": 400,
"msg": '验证码错误'
})
# 4.如果一致 验证码通过
return Response({
"code":200,
"msg":'验证码相同'
})
-------------------------------------------------------------------------------------------
***路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/image/code/',views.VerImage.as_view()),# 检测验证码
]
前端:
methods: {
// 生成图片验证码地址
genImageCode() {
// 生成一个uuid
this.imageCodeID = uuid4() //将uuid理解为随机的字符串
// 生成一个图片验证码地址
this.iamgeCodeUrl = "user/check/imge/" + this.imageCodeID + "/"
},
功能七 用户的注册按钮勾选
注册的类视图
class Regview(APIView):
def post(self,reuqest):
user_name=reuqest.data.get('user_name')
password=reuqest.data.get('password')
mobile=reuqest.data.get('mobile')
agree=reuqest.data.get('agree')
# 判断用户协议
if not int(agree): # 转协议 因为字符串的0,不可用not来判断
return Response({
'code': 400,
'msg': '勾选协议'
})
if not user_name or not password or not mobile:
return Response({
'code':400,
'msg':'输入结果有误'
})
try:# 写入数据库
User.objects.create(
user_name=user_name,
mobile=mobile,
password=password
)
return Response({
'code': 200,
'msg': '注册成功'
})
# 否则执行注册失败
except Exception as e:
return Response({
'code': 400,
'msg': '注册失败'
})
----------------------------------------------------------------------------------
***路由***
from django.urls import path
from users import views
urlpatterns = [
path('check/reg/',views.Regview.as_view()),
]
前端:
// 用户注册
Register() {
// 是否同意用户协议
if (!this.aggree) {
this.flag = true
return
}
// 已勾选,则不显示提示信息
this.flag = false
// 通过element自定义表单校验规则,校验用户输入的用户信息
this.$refs["ruleForm"].validate((valid) => {
if (valid) {
// TODO 注册用户
******************************************************************
this.$axios.post('/user/check/reg/',{
'user_name':this.RegisterUser.name,
'password':this.RegisterUser.pass,
'mobile':this.RegisterUser.mobile,
'agree':this.aggree,
}).then((resp) => {
if (resp.data.code==200){
this.RegisterUser.name="",
this.RegisterUser.pass="",
this.RegisterUser.mobile="",
this.RegisterUser.confirmPass="",
//关闭注册弹窗
this.isRegister=false,
this.notifySucceed(resp.data.msg)
}else{
this.notifyError(resp.data.msg)
}
}).catch((err) => {
console.log(err)
alert('页面报错')
});