[django项目] 用户注册功能 之 用户模型与图片验证码

用户注册功能

之前我们完成了模板的抽取和配置, 前端的目标基本完成, 接下来开始对功能的设计与编写

由浅入深, 先从最基础的用户注册功能来设计

I. 用户模型设计

django的强大之处在于开发效率高,内置了权限模块之类的很多常用功能。在开始一个新的django项目时,如果权限模块中的User模型不满足项目要求,我们需要扩展或者自定义User模型。

扩展User模型的两种方法:(摘自官方文档)

  1. 如果你不需要改变数据库存储内容,只是改变行为,那么可以建立有一个基于User模型的代理模型。

  2. 如果想存储与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>接口设计思路

接口, 就是一个功能的使用说明书,那么一个网站页面的接口应该怎么设计呢?

  1. 分析业务逻辑,明确在这个业务中需要涉及到几个相关子业务,将每个子业务当做一个接口来设计
  2. 分析接口的功能任务,明确接口的访问方式与返回数据:
    • 接口的请求方式,如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">立即登录 &gt;</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>后端视图实现

  1. 事先安装好pillow包, 安装方法: pip install pillow
  2. 将生成图像验证码的模块文件夹captcha(点击获取代码)复制粘贴到项目根目录utils文件夹下,
  3. 由于验证(图片验证、短信验证)功能,以后有可能在其他应用或项目中重用,所以单独创建一个app, 来实现所有验证相关的业务逻辑接口。
  4. 在apps目录中创建一个verifications应用,并在settings.py文件中的INSTALLED_APPS列表中指定。
  5. 在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")
  1. 为了保存应用中用到的常量信息,需要在verifications应用下创建一个constants.py文件
# 在verifications/constants.py文件中加入如下代码:
# 保存常量
# 图片验证码过期时间
IMAGE_CODE_EXPIRES = 300

定义常量的目的是为了留一个接口, 方便日后修改

  1. 在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'),

]
  1. 记得主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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值