注册业务功能实现:
1、创建并注册用户应用
打开终端使用命令创建用户模块子应用,注意要创建在apps目录下
python ../manage.py startapp users
注册应用,找到settings文件的INSTALLED_APPS配置项添加users应用的注册
2、用户模型类
我们这里使用django的默认用户认证系统,并继承django默认的用户模型类AbstractUser,
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
"""自定义用户模型类"""
mobile = models.CharField(max_length=11, unique=True, verbose_name='手机号')
# 添加自定义字段mobile
class Meta:
db_table = 'tb_users'
verbose_name = '用户'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
定义完成后执行迁移操作
# 创建迁移文件
python manage.py makemigrations
# 执行迁移文件
python manage.py migrate
3、展示用户注册页面
3.1请求接口设计:
url | http://127.0.0.1:8000/register | ||
协议 | http | ||
请求方式 | GET |
前端发起请求,部分代码展示
<div class="login_btn fl" v-else>
<a href="{% url 'users:login'%}">登录</a>
<span>|</span>
<a href="{% url 'users:register'%}">注册</a>
</div>
3.2、定义用户注册路由
总路由:
re_path(r'^', include(("users.urls", 'users'), namespace="users")),
users应用中子路由:
from django.urls import path, re_path, include
from .views import RegisterView, LoginView, LogoutView, InfoView, resses_view, add_select_resses, put_delete_resses, \
histories_view,set_password,orders_view
urlpatterns = [
re_path(r'^register$', RegisterView.as_view(), name="register"),
]
3.3、定义用户注册视图:
class RegisterView(View):
def get(self, request):
return render(request, 'register.html')
访问接口,效果展示:
4、用户注册业务实现:
4.1、接口设计:
url | http://127.0.0.1:8000/register | ||
协议 | http | ||
请求方式 | POST |
请求携带参数:
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
username | string | 是 | 用户名 |
password | string | 是 | 密码 |
password2 | string | 是 | 确认密码 |
mobile | string | 是 | 手机号 |
allow | string | 是 | 是否同意用户协议 |
路由使用和前面GET请求一致
4.2、前端逻辑:
register.html
<div class="reg_form clearfix" id="app" v-cloak>
<form method="post" class="register_form" @submit="on_submit" action="{% url 'users:register'%}">
<!--当form表单没有指定url的时候,会自动将当前页面的地址作为url提交请求-->
{% csrf_token %}
<ul>
<li>
<label>用户名:</label>
<input type="text" name="username" id="user_name" v-model="username" @blur="check_username">
<span class="error_tip" v-show="error_name">[[ error_name_message ]]</span>
</li>
<li>
<label>密码:</label>
<input type="password" name="password" id="pwd" v-model="password" @blur="check_pwd">
<span class="error_tip" v-show="error_password">[[ error_password_message ]]</span>
</li>
<li>
<label>确认密码:</label>
<input type="password" name="password2" id="cpwd" v-model="password2" @blur="check_cpwd">
<span class="error_tip" v-show="error_check_password">[[ error_password2_message ]]</span>
</li>
<li>
<label>手机号:</label>
<input type="text" name="mobile" id="phone" v-model="mobile" @blur="check_phone">
<span class="error_tip" v-show="error_phone">[[ error_phone_message ]]</span>
</li>
<li class="agreement">
<input type="checkbox" name="allow" id="allow" checked="checked" v-model="allow"
@click="click_allow">
<label>同意”美多商城用户使用协议“</label>
<span class="error_tip" v-show="error_allow">[[ error_allow_message ]]</span>
{% if register_errmsg %}
<span class="error_tip2">{{ register_errmsg }}</span>
{% endif %}
</li>
<li class="reg_sub">
<input type="submit" value="注 册">
</li>
</ul>
</form>
</div>
js文件完成前端校验
var vm = new Vue({
el: '#app',
// 修改Vue变量的读取语法,避免和django模板语法冲突
delimiters: ['[[', ']]'],
data: {
host: host,
error_name: false,
error_password: false,
error_check_password: false,
error_phone: false,
error_image_code: false,
error_sms_code: false,
error_allow: false,
error_name_message: '请输入5-20个字符的用户',
error_password_message: '请输入8-20位的密码',
error_password2_message: '两次输入的密码不一致',
error_phone_message: '请输入正确的手机号码',
error_allow_message: '请勾选用户协议',
username: '',
password: '',
password2: '',
mobile: '',
allow: true
},
mounted: function () {
},
methods: {
// 检查用户名
check_username: function () {
var re = /^[a-zA-Z0-9_-]{5,20}$/;
if (re.test(this.username)) {
this.error_name = false;
alert("前端验证通过")
} else {
alert("前端验证不通过")
this.error_name_message = '请输入5-20个字符的用户名';
this.error_name = true;
}
// 检查密码
check_pwd: function () {
var re = /^[0-9A-Za-z]{8,20}$/;
if (re.test(this.password)) {
this.error_password = false;
} else {
this.error_password = true;
}
},
// 确认密码
check_cpwd: function () {
if (this.password != this.password2) {
this.error_check_password = true;
} else {
this.error_check_password = false;
}
},
// 检查手机号
check_phone: function () {
var re = /^1[345789]\d{9}$/;
if (re.test(this.mobile)) {
this.error_phone = false;
} else {
this.error_phone_message = '您输入的手机号格式不正确';
this.error_phone = true;
}
}
// 检查是否勾选协议
check_allow: function () {
if (!this.allow) {
this.error_allow = true;
} else {
this.error_allow = false;
}
},
click_allow: function () {
this.allow = !this.allow
this.check_allow()
},
// 表单提交
on_submit() {
alert("触发前端验证")
this.check_username();
this.check_pwd();
this.check_cpwd();
this.check_phone();
this.check_allow();
if (this.error_name == true || this.error_password == true || this.error_check_password == true
|| this.error_phone == true || this.error_allow == true) {
// 不满足注册条件:禁用表单
window.event.returnValue = false;
}
}
}
});
4.2、在之前的注册视图中继续编写实现注册业务的方法
class RegisterView(View):
def get(self, request):
return render(request, 'register.html')
def post(self, request):
username = request.POST.get("username")
password = request.POST.get("password")
password2 = request.POST.get("password2") # 确认密码
mobile = request.POST.get("mobile")
allow = request.POST.get("allow")
context = {
"register_errmsg": ""
}
if not all([username, password, password2, mobile, allow]):
context["register_errmsg"] = "参数不全"
return render(request, 'register.html', context)
if not re.match(r'^[0-9a-zA-Z_-]{5,20}$', username): # 后端校验:检查用户是否是5-20的任意字符
context["register_errmsg"] = "请输入5-20个字符的用户名"
return render(request, 'register.html', context)
if not re.match(r'^[0-9a-zA-Z_-]{8,20}$', password):
context["register_errmsg"] = "请输入8-20个字符的密码"
return render(request, 'register.html', context)
if password != password2:
context["register_errmsg"] = "密码与确认密码不一致"
return render(request, 'register.html', context)
if not re.match(r'^1[3578]\d{9}$', mobile): # 手机号码一般以1开头,第二位是3,5,7,8其中一位。总共11个数
context["register_errmsg"] = "手机号码格式错误"
return render(request, 'register.html', context)
# 使用django自己创建认证模型的创建方法,会在创建的时候自动为密码进行加密处理。后期进行登录验证的时候也就只能调用djaongo自带的认证模型进行解密处理
user = user_manage.objects.create_user(username=username, password=password, phone=mobile)
return redirect("users:login") # 注册成功,重定向回到登录页