一、用户模型设计(用户表的设计)
1. 用户表字段分析
1)用户名
2)密码
3)手机号
4)邮箱
5)邮箱是否有效
2. 用户模型设计
django设计模型开发效率极高,内置了许多功能,包括权限验证等等,也有自定义的User模型。
因此我们需要继承已经写好的抽象模型类AbstractBaseUser,它有已经封装好的各种方法,约定俗成的凡是抽象模型类起名都以Abstract来开头,但是判断该模型类是否是抽象模型类的依据是,类中需要定义
class Meta: abstract = True
这才证明它是一个抽象模型类。
在我们继承了django自带的用户模型类之后,我们使用时进行扩充字段即可。
3. 在User这个app中的models.py页面来填写我们的需要的User模型类
1)继承抽象模型类,添加用户新字段,重写管理器,方便我们创建用户,并制定我们的User模型使用我们自定义的管理器
# user/models.py 文件
from django.db import models from django.contrib.auth.models import AbstractUser, UserManager as _UserManager # Create your models here. # 自定义管理器(功能:创建用户时可以不用填写email) class UserManager(_UserManager): def create_superuser(self, username, password, email=None, **extra_fields): super().create_superuser(username=username, password=password, email=email, **extra_fields) class User(AbstractUser): """ 自定义的User模型,添加moblie,email_active字段 """ # 添加手机字段, 第一个'手机号'是数据库中备注信息,max_length是该字段的最大长度 # unique是该字段唯一,不能重复,help_text是在我们的admin后台来提示的字段信息 # error_messages是当插入字段出错时提示的报错信息 mobile = models.CharField('手机号',max_length=11, unique=True, help_text='手机号', error_messages={'unique':'此手机号已注册'}) # 添加一个邮箱是否激活的字段,默认值为False,及该邮箱未激活 email_active = models.BooleanField('邮箱激活状态',default=False) # 源信息,内嵌类,可以给我们的model定义元数据 class Meta: db_table = 'tb_user' # 指定数据库表名 verbose_name = '用户' # 在admin站点显示的名称 verbose_name_plural = verbose_name # 复数 # 为了方便在我们调用该类时可以看到我们创建的用户名称 def __str__(self): return self.username # 通过 createsuperuser 这个命令创建用户时,需要的字段 # 该参数里面的内容需要和我们上方唇膏就的字段名相同 REQUIRED_FIELDS = ['mobile'] # user模型相当强大,还有修改必须输出email这个行为 # 这时候就需要用到我们的管理器了object,可以查看AbstractUser这个模型类中的管理器 objects = UserManager() # UserManager这个就是管理器的内容,我们可以进行重写部分模块,来达到我们的自定义管理器的目的 # 因为我们需要创建用户时不需要必须填写email,我们创建用户时又需要用到createsuperuser这个命令 # 所以我们需要复写UserManager这个类中的create_superuser的方法,因为我们创建用户时,调用的就是这个方法 # 因为我们创建的自定义管理器不能和继承自带管理器的类同名,所以我们给继承的django的管理器起一个别名,再进行继承 # 在上方复写好了我们自定义的管理器后,需要在User模型类中指定该自定义管理器 objects = UserManager()
2)位置在apps文件夹中User应用中的models.py文件中
3) 在主目录下的settings文件中添加我们自定义模型类的地址(告诉整个项目我们的用户模型类已经修改了,并且位置在XXX)
# 注明我们的User模型的导入路径 AUTH_USER_MODEL = 'user.User' # user.User这个地址是因为我们创建的用户模型类是在user这个app下的User这个类作为用户模型类
4)在pycharm中进行远程连接我们的虚拟机
找到菜单栏中的Tools下面的start SSH session ,然后选择我们的远程主机地址连接即可。
如果出现了上图所示的乱码,则找到File----->Settings------>手动搜索encoding------>SSH Terminal----->里面的Default encoding来设置默认编码从GBK改为UTF-8即可。
修改成功后效果图如下(看到了正常的汉字):
5) 连接上存放远程解释器的虚拟机后,执行以下命令来创建我们用户模型类的映射文件:
workon tzproject # 进入我们项目使用的tzproject这个python虚拟环境 cd first_project/tzproject/ # 进入到我们虚拟机上所存放该项目的位置 ls # 查看一下我们的项目文件夹的内容是否正确 python manage.py makemigrations # 为我们创建的用户模型类创建映射文件,这里可以指定app的名称,也可以不指定,因为我们这是第一次创建映射文件,所以除了user这个app中的用户表需要创建外还需要生成一些权限表等等,所以我们第一次不指定app_name
效果图如下:
6)创建好映射文件后,我们需要通过migrate命令来通过映射文件在数据库中创建对应的表
壹:创建好映射文件后我们进入mysql数据库来查看我们的数据库中的内容
mysql -uroot -pqwe123 # 登录mysql show databases; # 显示所有数据库名称 use tzproject; # 进入项目我们对应创建的数据库 show tables; # 显示数据库中的所有表
可以看到我创建完映射文件后的数据库还是空的。
贰:此时需要注释主目录下的settings文件中的app注册中的admin,以及主目录下的urls.py文件中的admin,因为我们还会创建同名的类,不用它这个(需要注意的是,我们需要在创建完映射文件后,即执行完
makemigrations 这个命令后再注释admin,不然会报错的。)
叁:执行migrate命令在数据库中创建相应的表
python manage.py migrate # migrate也可以指定app名称或不指定,不指定就将我们映射文件中的所有表都在数据库中创建
此时查看我们的数据库中,可以看到已经创建出了很多的表了:
其中 tb_user 就是我们自己写的用户模型类创建的表,tb_user_groups 是 tb_user 和 auth_group两张表的中间表,tb_user_user_permissions 是 tb_user 和auth_permission的中间表。
肆:创建超级管理员,使用createsuperuser命令创建超级管理员
python manage.py createsuperuser # 创建超级用户 """ 输入用户名,手机号和密码,邮箱由于我们写的是自定义管理器,所以取消了必须输入邮箱的部分 """
二、功能需求分析
1. 接口设计思路
分析业务逻辑,明确在这个业务中需要涉及到的几个相关业务,把每个子业务当做一个接口来设计
分析接口的功能,明确接口的访问方式和返回数据
接口的请求方式: GET PUT POST DELTE
接口的URL定义
需要接受什么参数(路径参数,查询参数,表单,json)
返回的数据及数据格式
2. 注册功能分析
1) 流程(功能流程图).
2)功能接口(重点:发送一次请求就要作为一个接口)
注册页面
图形验证码
用户名校验是否注册
手机号校验是否注册
短信验证码
注册保护用户数据
3)导入模块规则
壹. 系统模块第一部分
贰. django模块第二部分
叁. 自己写的代码
三、注册页面
1. 接口设计
1)接口说明
2)返回数据
注册页面的html
2. 后端代码
1)前端页面(项目目录下的templates下的user应用下的register.html页面)
{% extends 'base/base.html' %} <!-- 继承html模板页面 --> {% load static %} <!-- 加载静态页面 --> {% block title %} <!-- 重写该页面自己的标题名称 --> 用户注册 {% endblock %} {% block css_self %} <!-- 重写该页面自己的css样式 --> <link rel="stylesheet" href="{% static 'css/user/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="javascript:void(0);" class="login">立即登录 ></a> </div> <form action="" method="post" class="form-contain"> <div class="form-item"> <input type="text" placeholder="请输入用户名" name="username" class="form-control" autocomplete="off"> </div> <div class="form-item"> <input type="password" placeholder="请输入密码" name="password" class="form-control"> </div> <div class="form-item"> <input type="password" placeholder="请输入确认密码" name="password_repeat" class="form-control"> </div> <div class="form-item"> <input type="tel" placeholder="请输入手机号" name="telephone" class="form-control" autocomplete="off" autofocus> </div> <div class="form-item"> <input type="text" placeholder="请输入图形验证码" name="captcha_graph" class="form-captcha"> <a href="javascript:void(0);" class="captcha-graph-img"> <img src="{% static 'images/captcha.png' %}" alt="验证码" title="点击刷新"> </a> </div> <div class="form-item"> <input type="text" placeholder="请输入短信验证码" name="sms_captcha" class="form-captcha" 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 %}
2)视图(first_project---->apps---->user--->views.py)
from django.shortcuts import render # 我们的类视图需要继承View这个类,所以我们需要导入该模块 from django.views import View def login(request): return render(request, 'user/login.html') # 注册页面(由于我们的注册页面之后还会发送post请求,为了避免麻烦,所以我们使用类视图,不用函数视图) # def register(request): # return render(request, 'user/register.html') class RegisterView(View): # 注册视图 def get(self,request): return render(request, 'user/register.html') def post(self,request): pass
3)url(first_project---->apps---->user--->urls.py)
4)主路由中设置分路由
四、图形验证码
1. 接口设计
1)接口说明
需要注意的是:我们添加的这个参数是为了避免我们的页面被浏览器缓存,造成无法刷新的状况。
2)返回数据
验证码图片
3)分析
由于我们图形验证码,用户名校验是否注册,手机号校验是否注册,短信验证码这几个接口都是属于校验的功能,所以我们可以新建app专门用来校验,方便我们以后进行复用。
壹:创建校验app
① 右键选择菜单栏中Tools下的start SSH session连接虚拟机,并选中你需要连接的虚拟机
连接成功效果如下:
② 进入到我们的项目目录下的apps目录下创建我们的校验app(verivication),需要注意的是,记得进入正确的python虚拟环境
workon tzproject # 进入正确的python虚拟环境 cd first_project/tzproject/apps/ # 进入项目目录下的apps目录下 python ../manage.py startapp verivication # 创建verivication应用(用来校验)
③ 下载新建的app到本地
下载成功后可以看到本地页出现了该文件夹:
④ 注册app(在主目录下的settings文件中进行注册)
2. 后端代码
1)验证码视图(first_project----->apps---->verivication---->views.py)
壹:由于生成图形验证码的功能可以直接在网上找,下载使用即可。
嫌麻烦也可以直接使用我的这个百度云中存放的:
链接:https://pan.baidu.com/s/1MlvO3bKoQHS8JEEjqjkCbA
提取码:g1bx
该模块需要依赖于pillow模块,所以我们需要在python虚拟环境中安装该模块
贰: 将网上下载好的生成验证码功能模块复制到我们的untils文件夹下
叁:在我们需要的视图中导入该模块
肆:在创建好的校验app的视图中填写生成并保存验证码的过程(first_project----->apps---->verivication---->views.py)
# 一、系统模块 import logging # 记录日志我们需要导入日志模块 # 二、django模块 from django.shortcuts import render # django渲染页面模块 from django.http import HttpResponse # django的响应模块(本视图由于我们返回图片验证码需要使用它) # 三、自己的库 from untils.captcha.captcha import captcha # 导入生成图形验证码的第三方模块 from . import constants # 导入我们创建的用来存放常量的py文件 # 日志器 logger = logging.getLogger('django') # 生成一个名叫django的日志器 # 生成图形验证码 def image_code_view(request): """ 功能:生成验证码 url : /image_code/ :param request: :return: """ # 1. 生成验证码(随机生成字符和图片) text,image = captcha.generate_captcha() # 调用该方法会给我们返回两个值,一个是验证码的文字内容,一个是验证码的图片 # 2. 在后端保存验证码(为了之后校验验证码是否正确,所以现在我们需要保存验证码) request.session['image_code'] = text # 将验证码文字部分存放在session中 # 给验证码一个过期时间,为了方便日后修改,我们在校验app中创建一个constants.py的文件,用来存放常量 # 导入方式为 from . import constants request.session.set_expiry(constants.IMAGE_CODE_EXPIRES) # 设置session过期时间 # 3. 记录一个日志 logger.info('Image_code:{}'.format(text)) # 4. 返回验证码图片 # image存储的是图片的二进制数据,content指定了返回的数据内容, # content_type指定了返回数据的类型,告诉浏览器我们返回的是一张图片 return HttpResponse(content=image, content_type='image/jpg')
2)验证码路由url(first_project----->apps---->verivication---->urls.py)
3) 设置主路由中的分路由
4) 注册页面上的验证码部分改成我们刚刚写好的url(html代码)
将我们原来图形验证码的图片的位置换成我们的url:
修改前
修改后
这个时候我们刷新我们的注册页面时,我们的图形验证码也会随之刷新。效果图如下:
5) 实现我们点击验证码即可以刷新验证码
壹:新建一个注册页面对应的js文件(first_project------>static------>js------>user------>register.js)
贰:在我们的register.html页面导入这个js文件
<!-- 重写该页面自己的js --> {% block script_self %} <script src="{% static 'js/user/register.js' %}"></script> {% endblock %}
叁: 填写js文件内容(实现刷新图形验证码,文件位置:first_project------>static------>js------>user------>register.js)
$(()=>{ //es6中的用法 // 1. 点击刷新我们的图片验证码 $('.captcha-graph-img img').click(function () { // 重新加载一下图片验证码的src即可 $(this).attr('src','../verification/image_code/?rand=' + Math.random()); }); });