【Django在线教育平台】05.用户注册功能实现
2019-06-04 本文已影响17人
吾星喵
专题:Django2.0.8+xadmin2实现在线学习网站
Django2.0.8+xadmin2实现在线学习网站,课程、讲师、机构、用户收藏功能。GitHub地址:https://github.com/xyliurui/OnlineLearningPlatform ;Django版本:2.0.8
更多内容请点击 我的博客 查看,欢迎来访。
用户注册
用户注册视图RegisterView(View)
书写我们对应要处理的view(RegisterView)
users/views.py
# 用户注册
class RegisterView(View):
def get(self, request):
return render(request, 'register.html')
用户注册url
from users.views import user_login, LoginView, RegisterView
urlpatterns = [
path('admin/', admin.site.urls),
path('xadmin/', xadmin.site.urls),
path('', TemplateView.as_view(template_name='index.html'), name='index'),
# path('login/', TemplateView.as_view(template_name='login.html'), name='login'),
# path('login/', user_login, name='login'),
path('login/', LoginView.as_view(), name='login'), # 基于类方法实现登录,这里是调用它的方法
path('register/', RegisterView.as_view(), name='register'),
]
创建注册模板register.html
pass
验证码库实现验证码
https://github.com/mbi/django-simple-captcha
安装
pip install django-simple-captcha
将 captcha 添加到settings.py应用中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'courses',
'organization',
'operation',
'xadmin',
'crispy_forms',
'reversion',
'captcha',
]
执行同步数据库
manage.py@DjangoOnlineLearningPlatform > migrate
添加到urls中
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('xadmin/', xadmin.site.urls),
path('', TemplateView.as_view(template_name='index.html'), name='index'),
# path('login/', TemplateView.as_view(template_name='login.html'), name='login'),
# path('login/', user_login, name='login'),
path('login/', LoginView.as_view(), name='login'), # 基于类方法实现登录,这里是调用它的方法
path('register/', RegisterView.as_view(), name='register'),
path('captcha/', include('captcha.urls')),
]
验证码展示到页面
users/forms.py
定义注册表单RegisterForm(forms.Form)
from captcha.fields import CaptchaField
class RegisterForm(forms.Form):
# 此处email与前端name需保持一致
email = forms.EmailField(required=True)
password = forms.CharField(required=True, min_length=5)
# 应用验证码
captcha = CaptchaField() # 如果验证码错误提示是英文,可以在括号内加入 error_messages={'invalid': '验证码错误'}
验证码实例化视图RegisterView(View)
users/views.py
在我们的registerform中实例化并传送到前端
from .forms import LoginForm, RegisterForm
# 用户注册
class RegisterView(View):
def get(self, request):
# print(request.build_absolute_uri()) # 地址为: http://127.0.0.1:8000/register/
register_form = RegisterForm()
# 图片验证码
# hashkey验证码生成的秘钥,image_url验证码的图片地址
hashkey = CaptchaStore.generate_key()
image_url = captcha_image_url(hashkey)
return render(request, 'register.html',
{
'register_form': register_form,
'hashkey': hashkey,
'image_url': image_url,
})
前端获取验证码值register.html
<h3>欢迎注册 在线学习平台</h3>
<p>创建一个新账户</p>
<form method="post" action="/register/" autocomplete="off">
<input name="email" value="{% if register_form.email.value %}{{ register_form.email.value }}{% endif %}" type="email" class="form-control" placeholder="请输入邮箱" required="">
{% if register_form.errors.email %}
<span class="help-block m-b-none"> {{ register_form.errors.email.as_text }}</span>
{% endif %}
<input name="password" value="{% if register_form.password.value %}{{ register_form.password.value }}{% endif %}" type="password" class="form-control" placeholder="请输入密码" required="">
{% if register_form.errors.password %}
<span class="help-block m-b-none"> {{ register_form.errors.password.as_text }}</span>
{% endif %}
<div class="input-group">
<input type="text" name="captcha_1" required="" id="id_captcha_1" class="form-control" autocapitalize="off" autocomplete="off" autocorrect="off" spellcheck="false" style="width: 75%" placeholder="验证码">
<img style="width: 25%; float: left; margin-top: 15px;height: 30px" src="{{ image_url }}" alt="captcha" class="captcha">
<input type="hidden" name="captcha_0" value="{{ hashkey }}" required="" id="id_captcha_0">
</div>
{# register_form.captcha #} <!-- 可以使用register_form表单自动生成表单框和验证码图片,但样式没调好,就是用上面方法了 -->
{#【{{ image_url }}、{{ hashkey }}】#}
{% if register_form.errors.captcha %}
<span class="help-block m-b-none"> {{ register_form.errors.captcha.as_text }}</span>
{% endif %}
{% csrf_token %}
{% if msg %}
<br>
<div class="alert alert-danger" style="padding: 5px;">
{{ msg }}
</div>
{% endif %}
<button type="submit" class="btn btn-primary block full-width m-b">注 册</button>
<p class="text-muted text-center"><small>已经有账户了?</small><a href="login.html">点此登录</a>
</p>
</form>
刷新验证码功能
http://django-simple-captcha.readthedocs.io/en/latest/usage.html
前端的form提交加上对应的crsf token
刷新验证码是前端帮我们完成的:
<script src="{% static 'js/jquery.min.js' %}"></script>
<script>
$('.captcha').click(function () {
$.getJSON("/captcha/refresh/", function (result) {
$('.captcha').attr('src', result['image_url']);
$('#id_captcha_0').val(result['key'])
});
});
</script>
BLOG_20190604_135308_74
获取注册表单保存数据库RegisterView(View)
获取前端页面值并封装成一个user_profile对象,保存到数据库。
密码加密
# 用户注册
class RegisterView(View):
def get(self, request):
register_form = RegisterForm()
# 图片验证码
# hashkey验证码生成的秘钥,image_url验证码的图片地址
hashkey = CaptchaStore.generate_key()
image_url = captcha_image_url(hashkey)
return render(request, 'register.html',
{
'register_form': register_form,
'hashkey': hashkey,
'image_url': image_url,
})
def post(self, request):
register_form = RegisterForm(request.POST)
# 图片验证码
hashkey = CaptchaStore.generate_key()
image_url = captcha_image_url(hashkey)
if register_form.is_valid():
user_name = request.POST.get("email", "")
pass_word = request.POST.get("password", "")
# 用户不为空字符串,且用户
if user_name.strip() != '' and not UserProfile.objects.filter(email=user_name):
# 实例化一个user_profile对象,将前台值存入
user_profile = UserProfile()
user_profile.username = user_name
user_profile.email = user_name
# 加密password进行保存
user_profile.password = make_password(pass_word)
user_profile.save()
# 发送邮件功能待写
return render(request, 'login.html')
else:
return render(request, 'register.html',
{
'register_form': register_form,
'msg': '邮箱已使用!',
'hashkey': hashkey,
'image_url': image_url,
})
return render(request, 'register.html',
{
'register_form': register_form,
'hashkey': hashkey,
'image_url': image_url,
})
发送邮件功能
发送邮件配置
修改settings.py
# 在标准输出中输出e-mail内容来代替通过SMTP服务发送邮件
# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# 实际发送邮件
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.yeah.net' # smtp地址
EMAIL_HOST_USER = 'xyliurui@yeah.net'
EMAIL_HOST_PASSWORD = 'lr99@ts.com'
EMAIL_PORT = 25 # smtp端口
EMAIL_USE_TLS = True
# DEFAULT_FROM_EMAIL = 'xyliurui@yeah.net'
# 可以使用这个表达形式
DEFAULT_FROM_EMAIL = 'DjangoAdmin <xyliurui@yeah.net>'
# 管理员站点
SERVER_EMAIL = 'xyliurui@yeah.net'
EMAIL_FROM = 'DjangoAdmin<xyliurui@yeah.net>' # 一般为登录用户,也就是=EMAIL_HOST_USER
发送邮件模块email_send.py
apps文件夹下,新建Package包,名字为utils,然后创建email_send.py文件
apps/utils/email_send.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from random import Random
from django.core.mail import send_mail
from users.models import EmailVerifyRecord
from django.conf import settings
# 生成随机字符串
def random_str(random_length=8):
s = ''
# 生成字符串的可选字符串
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
length = len(chars) - 1
for i in range(random_length):
s += chars[Random().randint(0, length)]
return s
# 发送注册邮件
def send_register_email(request_uri, 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 = '在线学习平台 注册激活链接'
email_body = '请点击链接激活账号:{}active/{}'.format(request_uri, code) # request_uri='http://127.0.0.1:8000/register/'
# 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list
send_status = send_mail(email_title, email_body, settings.EMAIL_FROM, [email])
if send_status:
return True
else:
return False
注册post视图中增加发送邮件RegisterView(View)
需要将新注册的用户设置为未激活user_profile.is_active = False,然后通过激活链接去激活
from utils.email_send import send_register_email
# 用户注册
class RegisterView(View):
def get(self, request):
# print(request.build_absolute_uri()) # 地址为: http://127.0.0.1:8000/register/
register_form = RegisterForm()
# 图片验证码
# hashkey验证码生成的秘钥,image_url验证码的图片地址
hashkey = CaptchaStore.generate_key()
image_url = captcha_image_url(hashkey)
return render(request, 'register.html',
{
'register_form': register_form,
'hashkey': hashkey,
'image_url': image_url,
})
def post(self, request):
register_form = RegisterForm(request.POST)
# 图片验证码
hashkey = CaptchaStore.generate_key()
image_url = captcha_image_url(hashkey)
if register_form.is_valid():
user_name = request.POST.get("email", "")
pass_word = request.POST.get("password", "")
# 用户不为空字符串,且用户
if user_name.strip() != '' and not UserProfile.objects.filter(email=user_name):
# 实例化一个user_profile对象,将前台值存入
user_profile = UserProfile()
user_profile.username = user_name
user_profile.email = user_name
# 加密password进行保存
user_profile.password = make_password(pass_word)
# 默认激活状态True,需要改为False
user_profile.is_active = False
user_profile.save()
# 发送注册激活邮件
send_register_email(request_uri=request.build_absolute_uri(), email=user_name, send_type='register')
return render(request, 'login.html')
else:
return render(request, 'register.html',
{
'register_form': register_form,
'msg': '邮箱已使用!',
'hashkey': hashkey,
'image_url': image_url,
})
return render(request, 'register.html',
{
'register_form': register_form,
'hashkey': hashkey,
'image_url': image_url,
})
测试注册发送验证码功能,填入正确的表单,输入正确的验证码,点击注册,即可收到邮件。
邮件链接激活
收到激活链接
邮件发送成功后,收到邮件
请点击链接激活账号:http://127.0.0.1:8000/register/active/6LeX4thafahodBy7
激活用户视图ActiveUserView(View)
from .models import UserProfile, EmailVerifyRecord
# 激活用户
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 = UserProfile.objects.get(email=email)
user.is_active = True
user.save()
return render(request, 'login.html',
{
'msg': '激活用户成功'
})
else:
register_form = RegisterForm()
hashkey = CaptchaStore.generate_key()
image_url = captcha_image_url(hashkey)
return render(request, 'register.html',
{
"msg": "您的激活链接无效",
'register_form': register_form,
'hashkey': hashkey,
'image_url': image_url,
})
激活用户url
from django.urls import path, re_path
urlpatterns = [
path('admin/', admin.site.urls),
path('xadmin/', xadmin.site.urls),
path('', TemplateView.as_view(template_name='index.html'), name='index'),
# path('login/', TemplateView.as_view(template_name='login.html'), name='login'),
# path('login/', user_login, name='login'),
path('login/', LoginView.as_view(), name='login'), # 基于类方法实现登录,这里是调用它的方法
path('register/', RegisterView.as_view(), name='register'),
re_path('register/active/(?P<active_code>.*)/', ActiveUserView.as_view(), name='user_active'), # 激活
path('captcha/', include('captcha.urls')),
]