Django+xadmin打造在线教育平台(四)

七、增加邮箱验证

1、为用户表增加字段

我们的用户表继承改写django认证系统的用户表,里面有is_active字段,但是这个字段默认是激活状态,所以为了方便,我们给用户表添加一个新的字段,标志用户是否激活。

给UserProfile模型类添加字段

is_start = models.BooleanField(default=False, verbose_name='是否激活')
from django.db import models
from django.contrib.auth.models import AbstractUser
from datetime import datetime
# Create your models here.


class UserProfile(AbstractUser):
    image = models.ImageField(upload_to='user/', max_length=200, verbose_name='用户头像', null=True, blank=True)
    nick_name = models.CharField(max_length=20, verbose_name='用户昵称', null=True, blank=True)
    birthday = models.DateTimeField(verbose_name='用户生日', null=True, blank=True)
    gender = models.CharField(choices=(('girl', ''), ('boy', '')), max_length=10, verbose_name='用户性别', default='girl')
    address = models.CharField(max_length=200, verbose_name='用户地址', null=True, blank=True)
    phone = models.CharField(max_length=11, verbose_name='用户手机', null=True, blank=True)
    # 这个字段控制激活
    is_start = models.BooleanField(default=False, verbose_name='是否激活')
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    def __str__(self):
        return self.username

    class Meta:
        verbose_name = '用户信息'
        verbose_name_plural = verbose_name


class BannerInfo(models.Model):
    image = models.ImageField(upload_to='banner/', verbose_name='轮播图片', max_length=200)
    url = models.URLField(default='http://www.atguigu.com', max_length=200, verbose_name='图片链接')
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    def __str__(self):
        return str(self.image)

    class Meta:
        verbose_name = '轮播图信息'
        verbose_name_plural = verbose_name


class EmailVerifyCode(models.Model):
    code = models.CharField(max_length=20, verbose_name='邮箱验证码')
    email = models.EmailField(max_length=200, verbose_name='验证码邮箱')
    send_type = models.IntegerField(choices=((1, 'register'), (2, 'forget'), (3, 'change')), verbose_name='验证码类型')
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    def __str__(self):
        return str(self.code)

    class Meta:
        verbose_name = '邮箱验证码'
        verbose_name_plural = verbose_name
user/models.py完整代码

2、配置settings文件

(1)、准备工作

自备163网易邮箱,登录设置,开启POP3/SMTP/IMAP服务,复制smtp服务器地址,并设置客户端授权密码

 (2)、配置settings

EMAIL_HOST = 'smtp.yeah.net'
EMAIL_PORT = 25
EMAIL_HOST_USER = '[email protected]'  # 你的邮箱
EMAIL_HOST_PASSWORD = '123456'    # 你的客户端密码
EAMIL_FROM = '[email protected]'  # 你的邮箱

3、定义发邮件的工具函数

在根目录下创建utils包,在utils包下创建send_mail_tool.py文件

(1)、创建验证码

# from random import choice
from random import randrange


def get_random_code(code_length):
    code = ''
    code_source = '12345666666789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'  # 码源
    # for i in range(code_length):
    #     # 随机选择一个字符
    #     code += choice(code_source)
    for i in range(code_length):
        string = code_source[randrange(0, len(code_source)-1)]
        code += string
    return code

(2)、发送邮件

from users.models import EmailVerifyCode
from django.core.mail import send_mail
from GuLiEdu.settings import EAMIL_FROM


def send_email_code(email, send_type):
    # 第一步:创建邮箱验证码对象,保存数据库,用来以后做对比
    code = get_random_code(6)
    a = EmailVerifyCode()
    a.email = email
    a.send_type = send_type
    a.code = code
    a.save()

    # 第二步:正式的发邮件功能
    if send_type == 1:
        send_title = '欢迎注册谷粒教育网站'
        send_body = '请点击一下链接激活您的账号:\n' \
                    'http://127.0.0.1:8000/users/user_active/' + code
        send_mail(send_title, send_body, EAMIL_FROM, [email])

4、配置子路由

from django.urls import path, re_path

from users.views import register, user_logout, user_login, user_active


app_name = 'users'

urlpatterns = [
    path('register/', register, name='register'),
    path('login/', user_login, name='login'),
    path('logout/', user_logout, name='logout'),
    re_path(r'user_active/(\w+)/$', user_active, name='user_active')   
]

5、编写视图函数

(1)、修改注册接口(加入发送邮件的功能)

扫描二维码关注公众号,回复: 7770159 查看本文章
def register(request):
    if request.method == 'GET':
        # 这里实例化form类,目的不是为了验证,而是为了使用验证码
        user_register_form = UserRegisterForm()

        return render(request, 'register.html', {
            'user_register_form': user_register_form
        })
    else:
        user_register_form = UserRegisterForm(request.POST)  # 验证表单
        if user_register_form.is_valid():  # 判断是否合法
            email = user_register_form.cleaned_data['email']
            password = user_register_form.cleaned_data['password']

            user_list = UserProfile.objects.filter(Q(username=email) | Q(email=email))
            if user_list:
                return render(request, 'register.html', {
                    'msg': '用户已经存在'
                })
            else:
                a = UserProfile()
                a.username = email    # 用户名存库
                a.set_password(password)   # 密码存库,经过处理
                a.email = email
                a.save()  # 保存
                # 发送激活邮件邮件
                send_email_code(email, 1)
                return HttpResponse('请尽快前往您的邮箱激活,否则无法登录')
                # return redirect(reverse('index'))
        else:
            return render(request, 'register.html', {
                'user_register_form': user_register_form
            })

(2)、修改登录接口(验证是否激活)

def user_login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        user_login_form = UserLoginForm(request.POST)
        if user_login_form.is_valid():  # 判断是否合法
            email = user_login_form.cleaned_data['email']
            password = user_login_form.cleaned_data['password']

            user = authenticate(username=email, password=password)   # 验证邮箱密码
            if user:
                if user.is_start:  # 判断是否激活
                    login(request, user)   # 登录
                    return redirect(reverse('index'))
                else:
                    return HttpResponse('请去您的邮箱激活,否则无法登录')
            else:
                return render(request, 'login.html', {
                    'msg': '邮箱或密码有误'
                })

        else:
            return render(request, 'login.html', {
                'user_login_form': user_login_form
            })

(3)、激活试图函数

def user_active(request, code):
    if code:  # 获取到邮件中的code
        email_ver_list = EmailVerifyCode.objects.filter(code=code)  # 在邮箱验证码表中查找code,获取到邮箱对象列表
        if email_ver_list:
            email_ver = email_ver_list[0]  # 获取邮箱对象
            email = email_ver.email    # 获取邮箱
            user_list = UserProfile.objects.filter(username=email)  # 获取用户对象列表
            if user_list:
                user = user_list[0]   # 获取用户对象
                user.is_start = True   # 更改用户激活状态
                user.save()  # 保存
                return redirect(reverse('users:login'))
            else:
                pass
        else:
            pass
    else:
        pass
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.urls import reverse

from users.models import UserProfile, EmailVerifyCode
from users.forms import *
from django.db.models import Q
from django.contrib.auth import authenticate, login, logout

from utils.send_mail_tool import send_email_code


def index(request):
    return render(request, 'index.html')


def register(request):
    if request.method == 'GET':
        # 这里实例化form类,目的不是为了验证,而是为了使用验证码
        user_register_form = UserRegisterForm()

        return render(request, 'register.html', {
            'user_register_form': user_register_form
        })
    else:
        user_register_form = UserRegisterForm(request.POST)  # 验证表单
        if user_register_form.is_valid():  # 判断是否合法
            email = user_register_form.cleaned_data['email']
            password = user_register_form.cleaned_data['password']

            user_list = UserProfile.objects.filter(Q(username=email) | Q(email=email))
            if user_list:
                return render(request, 'register.html', {
                    'msg': '用户已经存在'
                })
            else:
                a = UserProfile()
                a.username = email    # 用户名存库
                a.set_password(password)   # 密码存库,经过处理
                a.email = email
                a.save()  # 保存
                # 发送激活邮件邮件
                send_email_code(email, 1)
                return HttpResponse('请尽快前往您的邮箱激活,否则无法登录')
                # return redirect(reverse('index'))
        else:
            return render(request, 'register.html', {
                'user_register_form': user_register_form
            })


def user_login(request):
    if request.method == 'GET':
        return render(request, 'login.html')
    else:
        user_login_form = UserLoginForm(request.POST)
        if user_login_form.is_valid():  # 判断是否合法
            email = user_login_form.cleaned_data['email']
            password = user_login_form.cleaned_data['password']

            user = authenticate(username=email, password=password)   # 验证邮箱密码
            if user:
                if user.is_start:  # 判断是否激活
                    login(request, user)   # 登录
                    return redirect(reverse('index'))
                else:
                    return HttpResponse('请去您的邮箱激活,否则无法登录')
            else:
                return render(request, 'login.html', {
                    'msg': '邮箱或密码有误'
                })

        else:
            return render(request, 'login.html', {
                'user_login_form': user_login_form
            })


def user_logout(request):
    logout(request)
    return redirect(reverse('index'))


def user_active(request, code):
    if code:  # 获取到邮件中的code
        email_ver_list = EmailVerifyCode.objects.filter(code=code)  # 在邮箱验证码表中查找code,获取到邮箱对象列表
        if email_ver_list:
            email_ver = email_ver_list[0]  # 获取邮箱对象
            email = email_ver.email    # 获取邮箱
            user_list = UserProfile.objects.filter(username=email)  # 获取用户对象列表
            if user_list:
                user = user_list[0]   # 获取用户对象
                user.is_start = True   # 更改用户激活状态
                user.save()  # 保存
                return redirect(reverse('users:login'))
            else:
                pass
        else:
            pass
    else:
        pass
users/views.py完整代码

猜你喜欢

转载自www.cnblogs.com/huiyichanmian/p/11809549.html