用户注册功能
之前我们完成了模板的抽取和配置, 前端的目标基本完成, 接下来开始对功能的设计与编写
由浅入深, 先从最基础的用户注册功能来设计
I. 用户模型设计
django的强大之处在于开发效率高,内置了权限模块之类的很多常用功能。在开始一个新的django项目时,如果权限模块中的User模型不满足项目要求,我们需要扩展或者自定义User模型。
扩展User模型的两种方法:(摘自官方文档)
-
如果你不需要改变数据库存储内容,只是改变行为,那么可以建立有一个基于User模型的代理模型。
-
如果想存储与User模型关联的信息,可以使用OneToOneField到包含其他信息字段的模型。这种one-to-one模型经常被称作Profile模型,因为它可能存储站点用户的非身份验证的相关信息。例如:
from django.contrib.auth.models import User class Employee(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) department = models.CharField(max_length=100)
自定义User模型:
如果你开始一个新项目,强烈建议建立一个自定义的用户模型,即使默认的用户模型是够你用的。 此模型的行为与默认用户模型相同,但如果需要,你将来可以自定义它:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
用户模型代码
根据上面的分析我们的用户模型代码如下
from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager as _UserManager
class UserManager(_UserManager):
"""
# 修改创建superuser时必须输入email的行为
"""
def create_superuser(self, username, password, email=None, **extra_fields):
# 用super调用create_superuser方法创建超级用户
super().create_superuser(username=username, password=password, email=email, **extra_fields)
# 这种修改源码的操作遵循面向对象大法
class User(AbstractUser):
"""
自定义User模型, 添加mobile,email_active字段
https://docs.djangoproject.com/en/2.1/ref/contrib/auth/#user-model
"""
mobile = models.CharField('手机号', max_length=11, unique=True,
help_text='手机号', error_messages={'unique':"此手机号已注册"})
email_active = models.BooleanField('邮箱状态', default=False)
class Meta:
db_table = 'tb_user' # 指定数据库表名
verbose_name = '用户' # admin站点中展示的名称
verbose_name_plural = verbose_name # 复数
def __str__(self): # 调用对象时打印
return self.username
# 通过create superuser命令创建用户时, 需要的字段, 如果不改默认为email
REQUIRED_FIELDS = ['mobile']
# 管理器实例化为UserManager
objects = UserManager()
编写完models要在settings.py文件中添加如下配置:
# 指定自定义用户模型
AUTH_USER_MODEL = 'users.User'
注意:先设置AUTH_USER_MODEL
再去运行迁移建立数据表。一旦已经创立数据库表之后再去修改AUTH_USER_MODEL
,会困难很多,因为它会影响着外键和多对多关系。这个改动并不能自动完成,需要手动修复(巨坑)。官方文档
启动迁移
方法1
运行ssh Terminal, workon
切换虚拟环境, 然后cd
到项目根目录(manage.py), 输入python manage.py makemigrations
回车, 再输入python manage.py migrate
回车, 即可迁移成功
方法2
写好后, 要执行迁移, pycharm 点击Tools
-> Run manage.py Task
, 或按快捷键Ctrl+Alt+R
然后输入makemigrations
回车, 再输入migrate
回车, 即可迁移成功, 可以通过用pycharm链接数据库查看
II.功能需求分析
1>接口设计思路
接口, 就是一个功能的使用说明书,那么一个网站页面的接口应该怎么设计呢?
- 分析业务逻辑,明确在这个业务中需要涉及到几个相关子业务,将每个子业务当做一个接口来设计
- 分析接口的功能任务,明确接口的访问方式与返回数据:
- 接口的请求方式,如GET 、POST 、PUT等
- 接口的URL路径定义
- 需要接收什么参数, 前端传递的数据及数据格式(如路径参数、查询参数、请求体表单、JSON等)
- 返回给前端的数据及数据格式
2>注册功能分析
- 判断用户名是否存在, 在输入用户名之后, 应该验证改用户是否被注册, 并弹出提示信息
- 判断手机号是否存在, 同上
- 图片验证码, 校验图片验证码, 只有校验成功才可以获取短信验证码
- 短信验证码, 通过外接平台api发送短信, 校验成功才可以注册
- 注册保存用户数据
图片验证码、短信验证码考虑到后续可能会在其他业务中也会用到,因此将验证码功能独立出来,创建一个新应用verifications,在此应用中实现图片验证码、短信验证码
III. 注册页面
1>接口设计
1.1>接口说明
条目 | 说明 |
---|---|
请求方法 | GET |
URL定义 | /users/register |
参数格式 | 无参数 |
1.2>返回参数
注册页面的HTML
2>视图代码
# 在users/view.py中添加以下代码
class RegisterView(View):
"""
注册视图
/users/register
"""
def get(self, request):
"""
凡是来访问这个视图的请求, 就返回注册页面
:param request: 请求注册页面
:return: 注册页面
"""
return render(request, 'users/register.html')
3>前端代码
{% extends 'base/base.html' %}
{% load static %}
{% block title %}用户注册{% endblock %}
{% block link %}
<link rel="stylesheet" href="../../static/css/users/auth.css">
{% endblock %}
{% block main %}
<!-- container start -->
<main id="container">
<div class="register-contain">
<div class="top-contain">
<h4 class="please-register">请注册</h4>
<a href="{% url 'users:login' %}" class="login">立即登录 ></a>
</div>
<form action="" method="post" class="form-contain">
{% csrf_token %}
<div class="form-item">
<input type="text" placeholder="请输入用户名" id="user_name" name="username" class="form-control"
autocomplete="off">
</div>
<div class="form-item">
<input type="password" placeholder="请输入密码" id="password" name="password" class="form-control">
</div>
<div class="form-item">
<input type="password" placeholder="请输入确认密码" id="re_password" name="password_repeat"
class="form-control">
</div>
<div class="form-item">
<input type="tel" placeholder="请输入手机号" id="mobile" name="telephone" class="form-control"
autocomplete="off" autofocus>
</div>
<div class="form-item">
<input type="text" placeholder="请输入图形验证码" id="input_captcha" name="captcha_graph"
class="form-captcha">
<a href="javascript:void(0);" class="captcha-graph-img">
<img src="#" alt="验证码" title="点击刷新">
</a>
</div>
<div class="form-item">
<input type="text" placeholder="请输入短信验证码" name="sms_captcha" class="form-captcha" id="input_smscode"
autocomplete="off">
<a href="javascript:void(0);" class="sms-captcha" title="发送验证码">获取短信验证码</a>
</div>
<div class="form-item">
<input type="submit" value="立即注册" class="register-btn">
</div>
</form>
</div>
</main>
<!-- container end -->
{% endblock %}
{% block script %}
<script src="{% static 'js/users/register.js' %}"></script>
{% endblock %}
IIII. 图片验证码接口代码实现
1>接口设计
1.1>接口说明
条目 | 说明 |
---|---|
请求方法 | GET |
URL定义 | /image_codes/ |
参数格式 | 查询参数 |
1.2>参数说明
对于图片的标识参数我们可以有多种设计选择, 就小编所知而言, 即可以通过js生成随机浮点数字符串作为标识, 也可以使用uuid(通用唯一识别码Universally unique identifier)来对图片进行标识, 这里我们去繁从简, 选择前者
参数 | 类型 | 前端是否必须传 | 描述 |
---|---|---|---|
rand | 字符串 | 否 | 随机浮点数字符串 |
2>后端视图实现
- 事先安装好
pillow
包, 安装方法:pip install pillow
- 将生成图像验证码的模块文件夹
captcha
(点击获取代码)复制粘贴到项目根目录utils文件夹下, - 由于验证(图片验证、短信验证)功能,以后有可能在其他应用或项目中重用,所以单独创建一个app, 来实现所有验证相关的业务逻辑接口。
- 在apps目录中创建一个verifications应用,并在settings.py文件中的INSTALLED_APPS列表中指定。
- 在verifications/views.py文件中添加如下代码:
# 导入库的时候使用这种排版方式, 使代码更整洁, 更具有涵养
# 系统库
import logging
# django框架库
from django.http import HttpResponse
from django.shortcuts import render
# 第三方库
from utils.captcha.captcha import captcha
from . import constants
# 日志器
logger = logging.getLogger('django') # get到的日志器是在setting中定义的
def image_code_view(request):
"""
生成验证码
:URL /image_code/
:param request:
:return:
"""
# 1. 生成一个验证码, 随机生成字符串, 生成图片
text, image = captcha.generate_captcha()
# 2. 后台保存验证码, 为了等下校验
# 保存在session中
request.session['image_code'] = text
# 给定过期时间, 设置session过期时间, 使用过期时间常量
request.session.set_expiry(constants.IMAGE_CODE_EXPIRES)
# 3. 记录一个日志
logger.info('Image code:{}'.format(text))
# 4. 返回验证码图片
return HttpResponse(content=image, content_type="image/jpg")
- 为了保存应用中用到的常量信息,需要在verifications应用下创建一个constants.py文件
# 在verifications/constants.py文件中加入如下代码:
# 保存常量
# 图片验证码过期时间
IMAGE_CODE_EXPIRES = 300
定义常量的目的是为了留一个接口, 方便日后修改
- 在verifications应用下创建一个urls.py文件并添加如下内容:
from django.urls import path, re_path
from . import views
app_name = "verifications"
urlpatterns = [
path('image_codes/', views.image_code_view, name='image_code'),
]
- 记得主urlconf里也要修改哦
from django.urls import path, include
urlpatterns = [
# path('admin/', admin.site.urls),
# 首页
path('', include('news.urls')),
# 验证功能
path('', include('verification.urls')), # 引用验证码的url
# 用户注册登陆页
path('users/', include('users.urls')),
# 课程页面
path('course/', include('course.urls')),
# 下载文档页面
path('doc/', include('doc.urls')),
]
3>前端代码实现
3.1>点击刷新图片-JS
在static/js文件夹下创建一个users文件夹用户存放用户模块相关的js文件,在users文件下创建register.js文件。
$(()=>{
// 1. 点击刷新图片验证码
$('.captcha-graph-img img').click(function () {
$(this).attr('src', '/image_code/?rand=' + Math.random())
// 生成rand用于标识, 使浏览器重新发送请求以刷新图片
})
});
3.2>引用图片验证码-html
{% extends 'base/base.html' %}
{% load static %}
{% block title %}
注册页
{% endblock %}
{% block link %}
<link rel="stylesheet" href="../../static/css/authPro/auth.css">
{% endblock %}
{% block main %}
<!-- container start -->
...
<a href="javascript:void(0);" class="captcha-graph-img">
<img src="{% url 'verification:verify' %}" alt="验证码" title="点击刷新">
</a>
...
<!-- container end -->
{% endblock %}
{% block script %}
<script src="{% static 'js/users/register.js' %}"></script>
{% endblock %}
页面效果:
完成!这样注册页面上的图片验证码就可以显示,并且点击就会刷新
项目源码:https://gitee.com/hao4875/newssite/tree/master