博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django+xadmin打造在线教育平台(三)
阅读量:4986 次
发布时间:2019-06-12

本文共 13415 字,大约阅读时间需要 44 分钟。

 

代码

五、用户注册

 主要实现功能

  • 用户输入邮箱、密码和验证码,点注册按钮
  • 如果输入的不正确,提示错误信息
  • 如果正确,发送激活邮件,用户通过邮件激活后才能登陆
  • 即使注册功能,没有激活的用户也不能登陆

5.1.初步视图

users/views.py

class RegisterView(View):    '''用户注册'''    def get(self,request):        return render(request,'register.html')

 用户以get方式,直接返回注册页面

5.2.路由设计

# MxOnline/urls.pyfrom users.views import RegisterView    path('register/',RegisterView.as_view(),name = 'register'),

urls中。通过类的as_view方法,调用这个View类

5.3.模板修改

修改index.html

点 “注册 ”应该跳到用户注册页面

修改register.html中的静态文件地址

{% load staticfiles %}
...

测试一下从index界面点注册能不能跳到register界面

 5.4.验证码

 验证码库:,这里面有介绍这个第三方库的使用方法

 安装:

pip install  django-simple-captcha

Add captcha to the INSTALLED_APPS in your settings.py

INSTALLED_APPS = [    'captcha',]

Add an entry to your urls.py:

urlpatterns = [    path('captcha/',include('captcha.urls')),]

生成到数据库

python manage.py makemigrationspython manage.py migrate

可以看到数据库多了一张表

 

 在注册页面显示验证码

 定义我们的register form:

# users/forms.pyfrom captcha.fields import CaptchaFieldclass RegisterForm(forms.Form):    '''注册验证表单'''        email = forms.EmailField(required=True)    password = forms.CharField(required=True,min_length=5)    # 验证码,字段里面可以自定义错误提示信息    captcha = CaptchaField()
 
forms.py
通过{
{ register_form.captcha }}获取验证码
{
{ register_form.captcha }}

 

 5.5.完善注册的后台逻辑

class RegisterView(View):    '''用户注册'''    def get(self,request):        register_form = RegisterForm()        return render(request,'register.html',{'register_form':register_form})    def post(self,request):        register_form = RegisterForm(request.POST)        if register_form.is_valid():            user_name = request.POST.get('email', None)            # 如果用户已存在,则提示错误信息            if UserProfile.objects.filter(email = user_name):                return render(request, 'register.html', {'register_form':register_form,'msg': '用户已存在'})            pass_word = request.POST.get('password', None)            # 实例化一个user_profile对象            user_profile = UserProfile()            user_profile.username = user_name            user_profile.email = user_name            user_profile.is_active = False            # 对保存到数据库的密码加密            user_profile.password = make_password(pass_word)            user_profile.save()            send_register_eamil(user_name,'register')            return render(request,'login.html')        else:            return render(request,'register.html',{'register_form':register_form})
 
views.py所以代码

说明:

  • 如果是get请求,直接返回注册页面给用户
  • 如果是post请求,先生成一个表单实例,并获取用户提交的所有信息(request.POST)
  • is_valid()方法,验证用户的提交信息是不是合法
  • 如果合法,获取用户提交的email和password
  • 实例化一个user_profile对象,把用户添加到数据库
  • 默认添加的用户是激活状态(is_active=1表示True),在这里我们修改默认的状态(改为is_active = False),只有用户去邮箱激活之后才改为True
  • 对密码加密,然后保存,发送邮箱,username是用户注册的邮箱,‘register’表明是注册
  • 注册成功跳转到登录界面

5.6.发送激活邮件

在Python中已经内置了一个smtp邮件发送模块,Django在此基础上进行了简单地封装,让我们在Django环境中可以更方便更灵活的发送邮件。

所有的功能都在django.core.mail中。

首先settings里面设置

# settings.pyEMAIL_HOST = "smtp.qq.com"  # SMTP服务器主机EMAIL_PORT = 25             # 端口EMAIL_HOST_USER = "1184405959@qq.com"       # 邮箱地址EMAIL_HOST_PASSWORD = "dwjybikexxxxxxxx"    # 密码EMAIL_USE_TLS= TrueEMAIL_FROM = "1184405959@qq.com"            # 邮箱地址

说明:

   EMAIL_HOST = "smtp.qq.com"

   EMAIL_HOST_PASSWORD = "dwjybikexxxxxxxx"

要想用qq邮箱作为服务器发送邮件,必须先开启SMTP,方法如下:

1)登录邮箱,找到“设置”-->>“用户”

2)往下拉找到SMTP服务,点开启,然后点“生成授权码”

3)可以看到授权码,“EMAIL_HOST_PASSWORD”里面填写的就是下面生成的授权码,而不是你的邮箱密码

 

在apps目录新建package utils,然后新建一个email_send.py文件

# apps/utils/email_send.pyfrom random import Randomfrom django.core.mail import send_mailfrom users.models import EmailVerifyRecordfrom MxOnline.settings import EMAIL_FROM# 生成随机字符串def random_str(random_length=8):    str = ''    # 生成字符串的可选字符串    chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'    length = len(chars) - 1    random = Random()    for i in range(random_length):        str += chars[random.randint(0, length)]    return str# 发送注册邮件def send_register_eamil(email, send_type="register"):    # 发送之前先保存到数据库,到时候查询链接是否存在    # 实例化一个EmailVerifyRecord对象    email_record = EmailVerifyRecord()    # 生成随机的code放入链接    code = random_str(16)    email_record.code = code    email_record.email = email    email_record.send_type = send_type    email_record.save()    # 定义邮件内容:    email_title = ""    email_body = ""    if send_type == "register":        email_title = "NBA注册激活链接"        email_body = "请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/{0}".format(code)        # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,发件人邮箱地址,收件人(是一个字符串列表)        send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])        # 如果发送成功        if send_status:            pass

 官方文档:

def send_mail(subject, message, from_email, recipient_list,              fail_silently=False, auth_user=None, auth_password=None,              connection=None, html_message=None):

前面四个参数必须要,后面的参数可以为空

发送电子邮件的最简单方法是使用 django.core.mail.send_mail()

subjectmessagefrom_emailrecipient_list参数是必需的。

  • subject:一个字符串。
  • message:一个字符串。
  • from_email:一个字符串。
  • recipient_list:字符串列表,每个字符串都是电子邮件地址。每个成员都recipient_list将在电子邮件的“收件人:”字段中看到其他收件人。
  • fail_silently:一个布尔值。如果是的话Falsesend_mail会提出一个。有关可能的例外列表,请参阅文档,所有这些例外都是。的子类 。
  • auth_user:用于向SMTP服务器进行身份验证的可选用户名。如果没有提供,Django将使用该设置的值 。
  • auth_password:用于验证SMTP服务器的可选密码。如果没有提供,Django将使用该设置的值 。
  • connection:用于发送邮件的可选电子邮件后端。如果未指定,将使用默认后端的实例。有关 更多详细信息,请参阅的文档。
  • html_message:如果html_message被提供,所得到的电子邮件将是一个 多部分/替代电子邮件message作为 文本/无格式内容类型和html_message作为 text / html的内容类型。

返回值将是成功传递消息的数量(可以是01因为它只能发送一条消息)。

 5.7.激活用户

根据邮箱找到对应的用户,然后设置is_active = True来实现

# 激活用户class ActiveUserView(View):    def get(self, request, active_code):        # 查询邮箱验证记录是否存在        all_record = EmailVerifyRecord.objects.filter(code = active_code)        if all_record:            for record in all_record:                # 获取到对应的邮箱                email = record.email                # 查找到邮箱对应的user                user = UserProfile.objects.get(email=email)                user.is_active = True                user.save()         # 验证码不对的时候跳转到激活失败页面        else:            return render(request,'active_fail.html')        # 激活成功跳转到登录页面        return render(request, "login.html", )

 在templates目录下创建 active_fail.html,代码如下:

    
Title

链接失效

 

激活邮箱的邮件如下:

 

修改login视图

添加一个判断,用户注册的后,等激活才能登陆

 
views.py

修改register.html

{% for key,error in register_form.errors.items %} {
{ error }} {% endfor %} {
{ msg }}
{% csrf_token %}

 修改的地方说明:

  • value="{
    { register_form.email.value }}
  • value="{
    { register_form.password.value }} 注册的用户不用再手动输入一遍邮箱和密码了
  • {% if login_form.errors.email %}errorput{% endif %}
  • {% if login_form.errors.password %}errorput{% endif %}
  • {% if login_form.errors.captchal %}errorput{% endif %}    提示错误信息并显示红框框
  • {
    { register_form.captcha }} 显示验证码

添加邮件激活的url

# MxOnline/urls.pyimport xadminfrom django.urls import path,include,re_pathfrom django.views.generic import TemplateViewfrom users.views import LoginView,RegisterView,ActiveUserViewurlpatterns = [    path('xadmin/', xadmin.site.urls),    path('', TemplateView.as_view(template_name='index.html'),name='index'),    path('login/',LoginView.as_view(),name = 'login'),    path('register/',RegisterView.as_view(),name = 'register'),    path('captcha/',include('captcha.urls')),    re_path('active/(?P
.*)/',ActiveUserView.as_view(),name='user_active'),]

 

六、找回密码

主要需要实现的功能:

  • 用户点“忘记密码”,跳到找回密码页面
  • 在forgetpwd页面,输入邮箱和验证码成功后,发送邮件提醒
  • 通过点击邮件链接,可以重置密码
  • 两次密码输的正确无误后,密码更新成功,跳到登录界面

6.1.路由设计

from users.views import ForgetPwdViewurlpatterns = [    path('forget/',ForgetPwdView.as_view(),name='forget_pwd'),]

6.2.初步视图函数

首先也需要个表单

forms.py

class ForgetPwdForm(forms.Form):    '''忘记密码'''    email = forms.EmailField(required=True)    captcha = CaptchaField(error_messages={'invalid': '验证码错误'})

视图函数

class ForgetPwdView(View):    '''找回密码'''    def get(self,request):        forget_form = ForgetPwdForm()        return render(request,'forgetpwd.html',{'forget_form':forget_form})

 

get方式,直接返回忘记密码的表单

6.3.模板修改

修改login.html中的url

把forgetpwd.html拷贝到templates文件下

修改静态文件路径

显示验证码

{
{ forget_pwd.captcha }}

 

6.4.添加发送找回密码邮件

修改utils/email_send.py

发送类型为“forget”

if send_type == "forget":        email_title = "NBA找回密码链接"        email_body = "请点击下面的链接找回你的密码: http://127.0.0.1:8000/reset/{0}".format(code)        # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list        send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])        # 如果发送成功        if send_status:            pass
 
email_send.py

6.5.完善找回密码的views

class ForgetPwdView(View):    '''找回密码'''    def get(self,request):        forget_form = ForgetPwdForm()        return render(request,'forgetpwd.html',{'forget_form':forget_form})    def post(self,request):        forget_form = ForgetPwdForm(request.POST)        if forget_form.is_valid():            email = request.POST.get('email',None)            send_register_eamil(email,'forget')            return render(request, 'send_success.html')        else:            return render(request,'forgetpwd.html',{'forget_form':forget_form})

用户提交邮箱后,提醒成功发送邮件

新建templates/send_success.html

    
Title

邮件已发送,请注意查收

修改forgetpwd.html

{
{ forget_form.captcha }}
{% for key,error in forget_from.errors.items %} {
{ error }} {% endfor %} {
{ msg }}

您还可以 [直接登录]

{% csrf_token %}

测试一下,输入邮箱和验证码看能不能收到邮件

 

6.6.重置密码

(1)重置密码激活邮箱的url

re_path('reset/(?P
.*)/', ResetView.as_view(), name='reset_pwd'),

(2)写重置密码(get方式)后台逻辑

class ResetView(View):    def get(self, request, active_code):        all_records = EmailVerifyRecord.objects.filter(code=active_code)        if all_records:            for record in all_records:                email = record.email                return render(request, "password_reset.html", {"email":email})        else:            return render(request, "active_fail.html")        return render(request, "login.html")

(3)创建修改密码的form表单

class ModifyPwdForm(forms.Form):    '''重置密码'''    password1 = forms.CharField(required=True, min_length=5)    password2 = forms.CharField(required=True, min_length=5)

(4)修改密码的url

上面那个是激活邮箱的url,有active_code参数,只能写get方式的逻辑。

这里必须单独新建一个修改密码的url,因为如果以post方式提交的话,post提交的地方跟get方式(url中需要active_code参数)的地址不一样,action="{% url 'modify_pwd' %}

path('modify_pwd/', ModifyPwdView.as_view(), name='modify_pwd'),

(5)修改密码的后台逻辑

class ModifyPwdView(View):    def post(self, request):        modify_form = ModifyPwdForm(request.POST)        if modify_form.is_valid():            pwd1 = request.POST.get("password1", "")            pwd2 = request.POST.get("password2", "")            email = request.POST.get("email", "")            if pwd1 != pwd2:                return render(request, "password_reset.html", {"email":email, "msg":"密码不一致!"})            user = UserProfile.objects.get(email=email)            user.password = make_password(pwd2)            user.save()            return render(request, "login.html")        else:            email = request.POST.get("email", "")            return render(request, "password_reset.html", {"email":email, "modify_form":modify_form })

(6)修改password_reset.html

    
密码修改

修改密码

已经通过验证,请设置新密码

  • 新 密 码 :
  • 确定密码:
  • {% for key,error in modify_form.errors.items %}{
    { key }}:{
    { error }}{% endfor %}{
    { msg }}
{% csrf_token %}

看一下整个流程有没有问题

首先在login界面点“忘记密码”,跳到forget页面

 

 

 

然后填上要找回密码的邮箱和验证码,提交后会收到邮件

点击链接,跳到修改密码页面

修改密码后,跳转到login页面

转载于:https://www.cnblogs.com/syq666/p/8715519.html

你可能感兴趣的文章
设置定点数学属性
查看>>
自动化测试工具 Test Studio入门教程
查看>>
排序算法(一) —— 冒泡排序
查看>>
No.026:Remove Duplicates from Sorted Array
查看>>
SpringBoot项目的几种创建方式,启动、和访问
查看>>
解决"disabled". Expected Boolean, got Number with value 0
查看>>
OC--init,initialize,initWithCoder:,initWithFrame:各方法的区别和加载顺序
查看>>
Exponentiation
查看>>
本地jar上传到本地仓库
查看>>
四则运算C++带Qt界面版本,吾王镇楼。。。。。
查看>>
各种获取时间的方法包含各类时间格式
查看>>
安卓7.0手机拍照闪退问题解决
查看>>
黑马程序员------IO(一)
查看>>
springcloud的配置
查看>>
ME525+ Defy+ 刷机指南[zz]
查看>>
支持触屏的jQuery轮播图插件
查看>>
差一点搞混了Transactional注解
查看>>
javascript基本函数
查看>>
C#转义字符
查看>>
前端公共库cdn服务推荐//提高加载速度/节省流量
查看>>