Django在线教育平台

【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')),
]
上一篇 下一篇

猜你喜欢

热点阅读