用Django编写邮箱注册以及验证码

1. 创建项目, 创建app, 创建temlplates, 创建static, 配置基础路由

能返回如下类似页面(博主使用的是Bootstrap的模板):

点击打开链接



2. 在models.py文件中, 自定义用户模型, 继承自Django默认的AbstractUser, 添加需要的字段(配置数据库的相关操作看博主其它博客)


为什么要自定义用户表?

因为默认的用户表字段满足不了注册信息的需求

from django.db import models

# Create your models here.
# 引入默认的用户模型类
from django.contrib.auth.models import AbstractUser


class UserProfile(AbstractUser):
    # 昵称
    # CharField的max_length是必填参数
    # verbose_name 后台管理界面中显示的字段名
    nick_name = models.CharField(max_length=20, verbose_name='昵称', default='')
    # 生日
    # blank=True 前端表单中的数据可以为空
    birday = models.DateTimeField(verbose_name='生日', null=True, blank=True)

    # 住址
    address = models.CharField(max_length=50, verbose_name='地址', default='')

    # 电话
    mobile = models.CharField(max_length=11, verbose_name='手机', default='')

    # 用户头像
    image = models.ImageField(upload_to='images/%Y/%m', default='image/default.png', verbose_name='头像')

    class Meta:
        db_table = 'Users'
        # 后台管理界面中显示的表的信息
        verbose_name = '用户信息'




3. 在定义一个邮件数据模型, 添加需要的字段

from datetime import datetime

# 邮箱验证类
class EmailVeriRecord(models.Model):
    # 验证码
    code = models.CharField(max_length=20, verbose_name='验证码')

    # 用户邮箱
    email = models.EmailField(max_length=50, verbose_name='用户邮箱')

    # datetime.now 在创建对象的时候, 再执行函数获取时间
    # 发送时间
    send_time = models.DateTimeField(default=datetime.now, verbose_name='发送时间', null=True, blank=True)

    # 过期时间
    exprie_time = models.DateTimeField(null=True)

    # 邮件类型
    # choices 枚举选项, 必须从指定的项中选择一个
    email_type = models.CharField(choices=(('register', '注册邮件'), ('forget', '找回密码')), max_length=10)

    class Meta:
        verbose_name = '邮件验证码'
        verbose_name_plural = verbose_name


4. 在settings中配置使用的用户模型 AUTH_USE_MODEL 设置自定义的用户模型

# 配置使用的用户模型
# app的名字
AUTH_USER_MODEL = 'app.UserProfile'


5. 打开run manage.py task, 执行makemigrations, 执行migrate

会在数据中生成如下一些数据库表:


6. 在admin.py文件中配置在后台显示的数据模型字段

from django.contrib import admin
from . models import UserProfile, EmailVeriRecord
# Register your models here.


# 注册自定义的用户模型
class UserProfileAdmin(admin.ModelAdmin):
    # 展示的字段
    list_display = ['username', 'nick_name', 'email', 'birday', 'mobile', 'address']
    # 根据某些字段进行搜索, 一般不会填写带有时间和日期的字段
    search_fields = ['username', 'nick_name', 'email', 'mobile']
    # 筛选器
    list_filter = ['birday']

# 注册数据模型和后台管理里
admin.site.register(UserProfile, UserProfileAdmin)


class EmailAdmin(admin.ModelAdmin):
    list_display = ['code', 'email', 'send_time', 'email_type']
    search_fields = ['code', 'email']
    list_filter = ['send_time', 'exprie_time']
admin.site.register(EmailVeriRecord, EmailAdmin)


7. 创建管理员账户


首先我们要新建一个用户名,用来登陆管理网站,可以使用如下命令

python manage.py createsuperuser


输入想要使用的用户名

Username (leave blank to use 'administrator'): user01

输入email

Email address: (在这里输入你的自己的邮箱帐号)


输入密码,需要输入两次,并且输入密码时不会显示出来

Password:

Password (again):

当两次密码都相同的时候,就会提示超级帐号创建成功。

Superuser created successfully.


运行服务

python manage.py runserver


浏览器地址栏输入:http://127.0.0.1:8000/admin

将你的账号密码填好, 会出现以下界面:


将你的账号密码填好, 会出现以下界面:


这时可以在settings.py中配置以下内容:

# 默认英文
# LANGUAGE_CODE = 'en-us'
# 配置显示中文界面
LANGUAGE_CODE = 'zh-hans'
# 时区
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

就会将页面转换成中文




8. 注册使用验证码, 下载django-simple-captcha包(建议使用豆瓣源下载)

在settings.py文件中注册app: captcha


INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app',
    'captcha',
]

在项目下的urls.py中声明captcha验证码路由


from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^', include('app.urls')),
    url(r'^captcha/', include('captcha.urls')),

]

最后, 执行makemigrations, 执行migrate创建数据表

会在数据库增添一张表:




9. 在app文件夹下新建forms.py文件, 创建RegisterFrom类, 声明form验证字段


# -*- coding: utf-8 -*-
# __author__ = 'ZKL'
# __date__ = '2018/4/24 15:04'

from django import forms
# 引入验证码的CaptchaField
from captcha.fields import CaptchaField


# 表单
class RegisterFrom(forms.Form):
    # 邮箱
    email = forms.EmailField(required=True, error_messages={'invalid': '请填写正确的邮箱地址'})
    # 密码
    password = forms.CharField(required=True, min_length=6, error_messages={'invalid': '密码不能少于6位'})
    rePassword = forms.CharField(required=True, min_length=6, error_messages={'invalid': '密码不能少于6位'})
    # 验证码
    captcha = CaptchaField(required=True, error_messages={'invalid': '验证码错误'})

10.在返回注册界面路由函数中, 创建RegisterFrom对象, 返回模板文件, 返回form, 在模板中展示验证码



from django.shortcuts import render, HttpResponse
from . forms import RegisterFrom
from . models import UserProfile
# make_password引入密码加密的函数
from django.contrib.auth.hashers import make_password
# Create your views here.
from utils.email_util import send_email


def index(request):
    if request.method == 'GET':
        # 构建form对象, 为了显示验证码
        form = RegisterFrom()
        return render(request, 'login.html', {'form': form})
    elif request.method == 'POST':
        # 验证form提交的数据
        form = RegisterFrom(request.POST)
        # 判断是否合法
        if form.is_valid():
            # 判断密码是否一致
            email = form.cleaned_data['email']
            pwd = form.cleaned_data['password']
            rePwd = form.cleaned_data['rePassword']
            # 两次密码不一致
            if pwd != rePwd:
                # 返回注册页面和错误信息
                return render(request, 'login.html', {'form': form, 'error': '两次密码不一致!'})
            # 判断用户是否存在
            # 根据email查找用户, 如果用户存在, 返回错误信息
            if UserProfile.objects.filter(email=email):
                # 用户已存在
                return render(request, 'login.html', {'form': form, 'errMsg': '该用户已存在!'})
            # 创建用户
            user = UserProfile(email=email, password=make_password(pwd))
            # 对用户传递过来的密码进行加密, 将加密之后的数据进行保存
            # 账户状态 未激活
            user.is_active = 0
            # 保存为邮箱地址, 可以使用邮箱登录后台
            user.username = email
            # 保存用户
            user.save()
            # 发送注册邮件
            if send_email(email, send_type='app'):
                # 注册邮件发送成功
                return HttpResponse('恭喜您注册成功, 激活邮件已发送至您的邮箱, 请登录后进行激活操作')
            else:
                return HttpResponse('恭喜您注册成功, 激活邮件发送')
        else:
            # 返回form表单
            # 返回注册页面, 信息回填, 显示错误信息
            return render(request, 'login.html', {'form': form})

11.注册账户流程:

   
1> 拿到表单数据先做表单验证,验证通过执行以下步骤,不通过直接返回注册页面及form信息
   
2> 取出表单中的数据,验证两次密码是否一致,一致执行以下步骤,不一致返回注册界面及form(信息回填)和错误信息
   
3> 根据表单中email搜索是否已有该用户,如果没有执行以下步骤,如果有返回注册界面及form(信息回填)和错误信息
   
4> 创建自定义用户模型对象,对密码进行加密,保存数据
   
5> 发送邮件
        5.1 生成随机验证码
        5.2 邮件发送相关配置
        5.3 拼接完整的激活地址,发送邮件
        5.4 返回发送结果
   
6> 判断发送结果,返回成功或失败信息


12: 发送邮件的代码我们新建一个utils文件夹并创建email_util.py文件


# -*- coding: utf-8 -*-
# __author__ = 'ZKL'
# __date__ = '2018/4/24 16:35'

from django.core.mail import send_mail
from app.models import EmailVeriRecord
import random
import datetime
from ZHUCE import settings
from datetime import timedelta


# 随机产生验证码的函数
def random_codechr(length=16):
    # 随机大小写组合的验证码
    chars = 'quFDGDbtwehykjahuhufHFCUHNCWEHAFDONCJUHU'
    codechr = ''
    for x in range(length):
        # 随机取出一个字符
        codechr += random.choice(chars)
    return codechr


#
def send_email(to_email, send_type='app'):
    """

    :param to_email: 收件人的邮箱
    :param send_type: 邮件类型
    :return: 邮件发送结果
    """
    email = EmailVeriRecord()
    # 获取验证码
    email.code = random_codechr()
    # 收件人
    email.email = to_email
    # 过期时间
    email.exprie_time = datetime.datetime.now() + datetime.timedelta(days=7)
    # 邮件类型
    email.send_type = send_type
    # 发送邮件
    try:
        res = send_mail('论坛激活邮件', '', settings.EMAIL_HOST_USER, [to_email], html_message='欢迎注册论坛, 点击链接激活你的账户:<a href="127.0.0.1:8000/active/{}">127.0.0.1:8000/active/{}</a>'.format(email.code, email.code))
        if res == 1:
            # 保存邮件记录
            email.save()
            return True
        else:
            return False
    except EmailVeriRecord as e:
        print(e)
        return False

13. 基本上就结束了, 为了全面在附上html代码


{% load static %}
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>注册</title>
      <style>
         .errorlist{
             padding-left: 0;
         }
          .errorlist > li{
              list-style: none;
              color: red;
              font-size: 19px;
          }
          .errborder{
              border-color: red;
              box-shadow: 0 0 5px red;
          }
      </style>
    <!-- Bootstrap core CSS -->
    <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">


    <!-- Custom styles for this template -->
    <link href="{% static 'css/singin.css' %}" rel="stylesheet">


    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
      <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
  </head>

  <body>

    <div class="container">

      <form class="form-signin" action="{% url 'index' %}" method="post">
          {% csrf_token %}
        <h2 class="form-signin-heading text-center">注册账户</h2>
{#      判断form中是否有email数据#}
        <label for="inputEmail" class="sr-only">邮箱地址</label>
        <input  name="email" type="email" id="inputEmail" class="form-control{% if errMsg %}errborder{% endif %}" placeholder="邮箱地址" required value="{% if form.email.value %} {{ form.email.value }} {% endif %}">
      {% if errMsg %}
       <h4>{{ errMsg }}</h4>
      {% endif %}
          {{ form.email.errors }}
        <input name="password" type="password" id="inputPassword" class="form-control {% if  error %}errborder{% endif %}" placeholder="密码" required value="{% if form.password.value %}{{ form.password.value }} {% endif %}">
       {{ form.password.errors }}
        <input name="rePassword" type="password" id="inputPassword" class="form-control {% if  error %}errborder{% endif %}" placeholder="确认密码" required value="{% if form.password.value %}{{ form.password.value }} {% endif %}">
      {% if error %}
          <h3>{{ error }}</h3>
      {% endif %}
          {{ form.captcha }}
          {{ form.captcha.errors }}
          <button class="btn btn-lg btn-primary btn-block" type="submit">注册</button>
      </form>
      <h3 class="text-center"><a href="login.html">已有账号?去登陆</a></h3>
    </div>
  </body>
</html>

14. 效果展示










未经允许, 禁止转载, 请自律!




猜你喜欢

转载自blog.csdn.net/qq_41664526/article/details/80069158