搭建本身的博客(三十):添加修改密码,忘记密码

一、修改的部分css

 

二、上代码html

{% load staticfiles %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <!-- 根据屏幕自动响应布局 -->
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>
        {#  用来放标题  #}
        {% block title %}

        {% endblock %}
    </title>
    {# 加载css代码 #}
    <link rel="stylesheet" href="{% static 'bootstrap4.1/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/base.css' %}">

    {# js代码放在后面能够增长性能 #}
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="{% static 'js/jquery-3.3.1.min.js' %}"></script>
    <script src="{% static 'bootstrap4.1/popper.min.js' %}"></script>
    <script src="{% static 'bootstrap4.1/bootstrap.min.js' %}"></script>

    {% block header_extends %}
        {#    用来作头部扩展,如加载某些静态文件     #}
    {% endblock %}
</head>
<body>

{# 导航栏 #}
<nav class="navbar navbar-expand-lg navbar-light bg-light sticky-top">
    <a class="navbar-brand" href="{% url 'home' %}">Felix Blog</a>

    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>


    <div class="collapse navbar-collapse" id="navbarSupportedContent">
        <ul class="navbar-nav mr-auto">
            <li class="nav-item nav-home"><a href="{% url 'home' %}" class="nav-link">首页</a></li>
            <li class="nav-item nav-blog"><a href="{% url 'blog_list' %}" class="nav-link">博客</a></li>
        </ul>

        <ul class="navbar-nav">
            {% if not user.is_authenticated %}
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'login' %}?from={{ request.get_full_path }}">登陆</a>
                </li>
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'register' %}?from={{ request.get_full_path }}">注册</a>
                </li>
            {% else %}
                <li class="nav-item dropdown">
                    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"
                       data-toggle="dropdown"
                       aria-haspopup="true" aria-expanded="false">
                        {{ user.username }}
                        {% if user.has_nickname %}
                            ({{ user.get_nickname }})
                        {% endif %}
                    </a>
                    <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                        <a class="dropdown-item" href="{% url 'user_info' %}">我的资料</a>
                        <a class="dropdown-item" href="{% url 'change_password' %}">修改密码</a>

                        {% if user.is_staff or user.is_superuser %}
                            <a class="dropdown-item" href="{% url 'admin:index' %}">后台管理</a>
                        {% endif %}
                        <div class="dropdown-divider"></div>
                        <a class="dropdown-item" href="{% url 'logout' %}?from={{ request.get_full_path }}">登出</a>
                    </div>
                </li>
            {% endif %}
        </ul>
    </div>
</nav>

{# 用来放内容 #}
{% block content %}

{% endblock %}

<!-- Modal 登陆模态框 -->
<div class="modal fade" id="login_model" tabindex="-1" role="dialog"
     aria-labelledby="exampleModalCenterTitle" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <form id="login_model_form" action="" method="post">
                <div class="modal-header">
                    <h5 class="modal-title">登陆</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    {% csrf_token %}
                    {% for field in login_model_form %}
                        <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                        {{ field }}
                    {% endfor %}
                    <span id="login_model_tip" class="text-danger"></span>
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-primary">登陆</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
                </div>
            </form>
        </div>
    </div>
</div>
<script>
    $('#login_model_form').submit(function (event) {
        $('#login_model_tip').text('');
        event.preventDefault(); // 阻止原事件提交
        $.ajax({
            url: '{% url 'login_for_model' %}',
            type: 'POST',
            data: $(this).serialize(),
            cache: false,
            success: function (data) {
                if (data['status'] === 'SUCCESS') {
                    window.location.reload();
                } else {
                    $('#login_model_tip').text('用户名或密码不正确')
                }
            }
        });
    })
</script>

{# 导入资源建议放在js代码前 #}
{# 用来放js代码 #}
{% block js %}

{% endblock %}

</body>
</html>
base.html
{% extends 'form.html' %}

{% block other-buttons %}
    <div id="send_code" class="btn btn-primary">发送验证码</div>
{% endblock %}

{% block js %}
    <script>
        $("#send_code").click(function () {
            if ($(this).hasClass('disabled')) {
                return false;
            }

            let email = $('#id_email').val();
            if (email === '') {
                $('#error-tip').text('邮箱不能为空');
                return false
            }
            let re_email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
            if (!re_email.test(email)) {
                alert('邮箱格式不正确');
                return false
            }

            // 发送验证码
            $.ajax({
                url: "{% url 'send_verification_code' %}",
                type: 'GET',
                data: {
                    'email': email,
                    'send_for':'bind_email_code',
                },
                cache: false,
                success: function (data) {
                    if (data['status'] === 'ERRORS') {
                        alert(data['msg']);
                    } else {
                        alert(data['msg']);
                    }

                }
            });

            // # 把按钮变灰
            $(this).addClass('disabled');
            $(this).attr("disabled", true);
            let time = 60;
            let interval = setInterval(() => {
                time -= 1;
                $(this).text(`再次发送(${time}s)`);
                if (time <= 0) {
                    // 时间等于0,进行复原
                    clearInterval(interval);
                    $(this).removeClass('disabled');
                    $(this).attr('disabled', false);
                    $(this).text('再次发送');
                    return false;
                }
            }, 1000);

        });
    </script>
{% endblock %}
user下的bind_email.html
{% extends 'form.html' %}

{% block other-buttons %}
    <div id="send_code" class="btn btn-primary">发送验证码</div>
{% endblock %}

{% block js %}
    <script>
        $("#send_code").click(function () {
            if ($(this).hasClass('disabled')) {
                return false;
            }

            let email = $('#id_email').val();
            if (email === '') {
                $('#error-tip').text('邮箱不能为空');
                return false
            }
            let re_email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
            if (!re_email.test(email)) {
                alert('邮箱格式不正确');
                return false
            }

            // 发送验证码
            $.ajax({
                url: "{% url 'send_verification_code' %}",
                type: 'GET',
                data: {
                    'email': email,
                    'send_for': 'forgot_password_code',
                },
                cache: false,
                success: function (data) {
                    if (data['status'] === 'ERRORS') {
                        alert(data['msg']);
                    } else {
                        alert(data['msg']);
                    }

                }
            });

            // # 把按钮变灰
            $(this).addClass('disabled');
            $(this).attr("disabled", true);
            let time = 60;
            let interval = setInterval(() => {
                time -= 1;
                $(this).text(`再次发送(${time}s)`);
                if (time <= 0) {
                    // 时间等于0,进行复原
                    clearInterval(interval);
                    $(this).removeClass('disabled');
                    $(this).attr('disabled', false);
                    $(this).text('再次发送');
                    return false;
                }
            }, 1000);

        });
    </script>
{% endblock %}
forgot_password.html
{% extends 'base.html' %}

{% block title %}
    个人博客|登陆
{% endblock %}

{% block content %}
    <div class="container">
        <div class="col-xl-6 offset-xl-3">
            {% if not user.is_authenticated %}
                <div class="card">
                    <h5 class="card-header">登陆</h5>
                    <div class="card-body">
                        <form action="" method="post">
                            {% csrf_token %}
                            {% for field in login_form %}
                                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                {{ field }}
                                <p class="text-danger">{{ field.errors.as_text }}</p>
                            {% endfor %}
                            <span class="text-danger float-left">{{ login_form.non_field_errors }}</span>
                            <div class="clearfix"></div>
                            <a class="float-left" href="{% url 'forgot_password' %}">忘记密码?</a>

                            <input type="submit" value="登陆" class="btn btn-primary float-right">
                        </form>
                    </div>
                </div>
                {# 未登陆跳转到首页 #}
            {% else %}
                <script>
                    window.location.href = '{% url 'home' %}'
                </script>
            {% endif %}
        </div>
    </div>
{% endblock %}

{% block js %}
    {# 将首页这个按钮设置激活状态 #}
    <script>
        $(".nav-home").addClass("active").siblings().removeClass("active");
    </script>
{% endblock %}
login.html
{% extends 'base.html' %}

{% block title %}
    个人博客|注册
{% endblock %}

{% block content %}
    <div class="container">
        {% if not user.is_authenticated %}
            <div class="col-xl-6 offset-xl-3">
            <div class="card">
                <h5 class="card-header">注册</h5>
                <div class="card-body">
                    <form action="{% url 'register' %}" method="post">
                        {% csrf_token %}
                        {% for field in reg_form %}
                            <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                            {{ field }}
                            <p class="text-danger">{{ field.errors.as_text }}</p>
                        {% endfor %}
                        <span class="text-danger">{{ login_form.non_field_errors }}</span>
                        <span id="error-tip" class="text-danger">{{ form.non_field_errors }}</span>
                        <div class="clearfix"></div>
                        <div id="send_code" class="btn btn-primary float-left">发送验证码</div>
                        <input type="submit" value="注册" class="btn btn-primary float-right">
                    </form>
                </div>
            </div>
        {% else %}
            <script>
                window.location.href = '{% url 'home' %}'
            </script>
        {% endif %}
        </div>
    </div>
{% endblock %}

{% block js %}
    {# 将首页这个按钮设置激活状态 #}
    <script>
        $(".nav-home").addClass("active").siblings().removeClass("active");
    </script>

    <script>

        $("#send_code").click(function () {
            if ($(this).hasClass('disabled')) {
                return false;
            }

            let email = $('#id_email').val();
            if (email === '') {
                $('#error-tip').text('邮箱不能为空');
                return false
            }
            let re_email = /^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
            if (!re_email.test(email)) {
                alert('邮箱格式不正确');
                return false
            }

            // 发送验证码
            $.ajax({
                url: "{% url 'send_verification_code' %}",
                type: 'GET',
                data: {
                    'email': email,
                    'send_for': 'register_code',
                },
                cache: false,
                success: function (data) {
                    if (data['status'] === 'ERRORS') {
                        alert(data['msg']);
                    } else {
                        alert(data['msg']);
                    }

                }
            });

            // # 把按钮变灰
            $(this).addClass('disabled');
            $(this).attr("disabled", true);
            let time = 60;
            let interval = setInterval(() => {
                time -= 1;
                $(this).text(`再次发送(${time}s)`);
                if (time <= 0) {
                    // 时间等于0,进行复原
                    clearInterval(interval);
                    $(this).removeClass('disabled');
                    $(this).attr('disabled', false);
                    $(this).text('再次发送');
                    return false;
                }
            }, 1000);

        });
    </script>
{% endblock %}
register.html
{% extends 'base.html' %}

{% block title %}
    我的资料
{% endblock %}

{% block content %}
    <div class="container">
        <div class="col-xl-8 offset-xl-2">
            <h2>{{ user.username }}</h2>
            {% if user.is_authenticated %}
                <ul>
                    <li>昵称:{{ user.get_nickname }} <a
                            href="{% url 'change_nickname' %}?from={{ request.get_full_path }}">修改昵称</a></li>
                    <li>
                        邮箱:
                        {% if user.email %}
                            {{ user.email }}
                        {% else %}
                            未绑定 <a href="{% url 'bind_email' %}?from={{ request.get_full_path }}">绑定邮箱</a>
                        {% endif %}
                    </li>
                    <li>上一次登陆时间:{{ user.last_login|date:"Y-m-d H:i:s" }}</li>
                    <li><a href="{% url 'change_password' %}">修改密码</a></li>
                </ul>
            {% else %}
                {# 未登陆跳转到首页 #}
                <script>
                    window.location.href = '{% url 'home' %}'
                </script>
            {% endif %}
        </div>
    </div>
    </div>
{% endblock %}

{% block js %}
    {# 将首页这个按钮设置激活状态 #}
    <script>
        $(".nav-home").addClass("active").siblings().removeClass("active");
    </script>
{% endblock %}
user_info.html
# -*- coding: utf-8 -*-
# @Time    : 18-11-20 下午8:10
# @Author  : Felix Wang

import re
from django import forms
from django.contrib import auth
from django.contrib.auth.models import User


class LoginForm(forms.Form):
    username_or_email = forms.CharField(label='用户名', required=True,
                                        widget=forms.TextInput(
                                            attrs={'class': 'form-control', 'placeholder': '请输入用户名或邮箱'}))
    # widget指定input标签类型
    password = forms.CharField(label='密码',
                               widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入密码'}))

    def clean(self):  # 验证数据
        username_or_email = self.cleaned_data['username_or_email']
        password = self.cleaned_data['password']
        user = auth.authenticate(username=username_or_email, password=password)
        if user is None:
            # 使用邮箱登陆
            if User.objects.filter(email=username_or_email).exists():
                username = User.objects.get(email=username_or_email).username
                user = auth.authenticate(username=username, password=password)
                if user is not None:
                    self.cleaned_data['user'] = user
                    return self.cleaned_data
            raise forms.ValidationError('用户名或密码错误')
        else:
            self.cleaned_data['user'] = user  # 将验证过的user放入clean_data
        return self.cleaned_data


class RegisterForm(forms.Form):
    # 用户名字段
    username = forms.CharField(label='用户名',
                               max_length=30,
                               min_length=3,
                               required=True,
                               widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'}))
    # 邮箱字段
    email = forms.EmailField(label='邮箱',
                             min_length=3,
                             required=True,
                             widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': '请输入邮箱'}))

    verification_code = forms.CharField(
        label='验证码',
        max_length=20,
        required=False,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '请输入验证码',
            }
        )
    )

    # 密码字段
    password = forms.CharField(label='密码',
                               min_length=6,
                               required=True,
                               widget=forms.PasswordInput(
                                   attrs={'class': 'form-control', 'placeholder': '请输入密码'}))
    # 再次输入密码
    password_again = forms.CharField(label='确认密码',
                                     min_length=6,
                                     required=True,
                                     widget=forms.PasswordInput(
                                         attrs={'class': 'form-control', 'placeholder': '请再输入一次密码'}))

    def __init__(self, *args, **kwargs):
        if 'requests' in kwargs:
            self.requests = kwargs.pop('requests')
        super().__init__(*args, **kwargs)

    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError('用户名已存在')
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('邮箱已存在')
        if not re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$', email):
            raise forms.ValidationError('邮箱格式错误')
        return email

    def clean_password_again(self):
        password = self.cleaned_data['password']
        password_again = self.cleaned_data['password_again']
        if password != password_again:
            raise forms.ValidationError('两次输入的密码不一致')
        return password_again

    def clean_verification_code(self):
        verification_code = self.cleaned_data.get('verification_code', '').strip().upper()
        if verification_code == '':
            raise forms.ValidationError('验证码不能为空')
        code = self.requests.session.get('register_code', '').upper()
        if code != verification_code or code == '':
            raise forms.ValidationError('验证码不正确')
        return verification_code


class ChangeNicknameForm(forms.Form):
    nickname_new = forms.CharField(
        label='新的昵称',
        max_length=20,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '请输入新的昵称',
            }
        )
    )

    def __init__(self, *args, **kwargs):
        if 'user' in kwargs:
            self.user = kwargs.pop('user')
        super().__init__(*args, **kwargs)

    # 表单验证
    def clean(self):
        # 判断用户是否登陆
        if self.user.is_authenticated:
            self.cleaned_data['user'] = self.user
        else:
            raise forms.ValidationError('用户还没有登陆')
        return self.cleaned_data

    def clean_nickname_new(self):
        nickname_new = self.cleaned_data.get('nickname_new', '').strip()
        if nickname_new == '':
            raise forms.ValidationError('新的昵称不能为空')
        return nickname_new


class BindEmailForm(forms.Form):
    email = forms.EmailField(
        label='邮箱',
        widget=forms.EmailInput(
            attrs={
                'class': 'form-control',
                'placeholder': '请输入邮箱',
            }
        )
    )

    verification_code = forms.CharField(
        label='验证码',
        max_length=20,
        required=False,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '请输入验证码',
            }
        )
    )

    def __init__(self, *args, **kwargs):
        if 'requests' in kwargs:
            self.requests = kwargs.pop('requests')
        super().__init__(*args, **kwargs)

    # 表单验证
    def clean(self):
        # 判断用户是否登陆
        if self.requests.user.is_authenticated:
            self.cleaned_data['user'] = self.requests.user
        else:
            raise forms.ValidationError('用户还没有登陆')

        # 判断用户是否已经绑定邮箱
        if self.requests.user.email != '':
            raise forms.ValidationError('你已经绑定邮箱')

        # 判断验证码
        code = self.requests.session.get('bind_email_code', '').upper()
        verification_code = self.cleaned_data.get('verification_code', '').upper()
        if code != verification_code or code == '':
            raise forms.ValidationError('验证码不正确')
        return self.cleaned_data

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('该邮箱已经被绑定')
        if not re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$', email):
            raise forms.ValidationError('邮箱格式错误')
        return email

    def clean_verification_code(self):
        verification_code = self.cleaned_data.get('verification_code', '').strip().upper()
        if verification_code == '':
            raise forms.ValidationError('验证码不能为空')
        return verification_code


class ChangePasswordForm(forms.Form):
    old_password = forms.CharField(label='旧的密码',
                                   min_length=6,
                                   required=True,
                                   widget=forms.PasswordInput(
                                       attrs={'class': 'form-control', 'placeholder': '请输入旧的密码'}))

    new_password = forms.CharField(label='新的密码',
                                   min_length=6,
                                   required=True,
                                   widget=forms.PasswordInput(
                                       attrs={'class': 'form-control', 'placeholder': '请输入新的密码'}))

    new_password_again = forms.CharField(label='请再次输入新的密码',
                                         min_length=6,
                                         required=True,
                                         widget=forms.PasswordInput(
                                             attrs={'class': 'form-control', 'placeholder': '请再次输入新的密码'}))

    def __init__(self, *args, **kwargs):
        if 'user' in kwargs:
            self.user = kwargs.pop('user')
        super().__init__(*args, **kwargs)

    def clean(self):
        # 验证新密码是否一致
        new_password = self.cleaned_data.get('new_password', '').strip()
        new_password_again = self.cleaned_data.get('new_password_again', '').strip()
        if new_password != new_password_again or new_password == '':
            raise forms.ValidationError('两次输入密码不一致')
        return self.cleaned_data

    def clean_old_password(self):
        # 验证旧的密码是否正确
        old_password = self.cleaned_data.get('old_password', '').strip()
        if not self.user.check_password(old_password):
            raise forms.ValidationError('旧的密码错误')

        return old_password


class ForgotPasswordForm(forms.Form):
    email = forms.EmailField(label='邮箱',
                             min_length=3,
                             required=True,
                             widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': '请输入绑定过的邮箱'}))

    verification_code = forms.CharField(
        label='验证码',
        max_length=20,
        required=False,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '请输入验证码',
            }
        )
    )
    new_password = forms.CharField(label='密码',
                                   min_length=6,
                                   required=True,
                                   widget=forms.PasswordInput(
                                       attrs={'class': 'form-control', 'placeholder': '请输入密码'}))

    def __init__(self, *args, **kwargs):
        if 'requests' in kwargs:
            self.requests = kwargs.pop('requests')
        super().__init__(*args, **kwargs)

    def clean_email(self):
        email = self.cleaned_data['email'].strip()
        if not User.objects.filter(email=email).exists():
            raise forms.ValidationError('邮箱不存在')
        return email

    def clean_verification_code(self):
        verification_code = self.cleaned_data.get('verification_code', '').strip().upper()
        if verification_code == '':
            raise forms.ValidationError('验证码不能为空')
        code = self.requests.session.get('forgot_password_code', '').upper()
        if code != verification_code or code == '':
            raise forms.ValidationError('验证码不正确')
        return verification_code
forms.py
from django.db import models
from django.contrib.auth.models import User


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    nickname = models.CharField(max_length=20, verbose_name='昵称', default='')

    def __str__(self):
        return '<Profile: {} for {}>'.format(self.nickname, self.user.username)


def get_nickname(self):
    if Profile.objects.filter(user=self).exists():
        profile = Profile.objects.get(user=self)
        return profile.nickname
    else:
        return ''


def get_nickname_or_username(self):
    if Profile.objects.filter(user=self).exists():
        profile = Profile.objects.get(user=self)
        return profile.nickname
    else:
        return self.username


def has_nickname(self):
    if Profile.objects.filter(user=self).exists():
        profile = Profile.objects.get(user=self)
        return True if profile.nickname.strip() else False
    return False


User.get_nickname = get_nickname  # 动态绑定方法
User.has_nickname = has_nickname  # 动态绑定方法
User.get_nickname_or_username = get_nickname_or_username  # 动态绑定方法
models.py
# -*- coding: utf-8 -*-
# @Time    : 18-11-4 下午5:22
# @Author  : Felix Wang

from django.urls import path
from . import views

urlpatterns = [
    path('login/', views.login, name='login'),  # 登陆
    path('logout/', views.logout, name='logout'),  # 登陆
    path('login_for_model/', views.login_for_model, name='login_for_model'),  # 登陆
    path('register/', views.register, name='register'),  # 注册
    path('user_info/', views.user_info, name='user_info'),  # 用户信息
    path('change_nickname/', views.change_nickname, name='change_nickname'),  # 更改昵称
    path('bind_email/', views.bind_email, name='bind_email'),  # 更改昵称
    path('send_verification_code/', views.send_verification_code, name='send_verification_code'),  # 更改昵称
    path('change_password/', views.change_password, name='change_password'),  # 更改密码
    path('forgot_password/', views.forgot_password, name='forgot_password'),  # 更改密码
]
urls.py
# -*- coding: utf-8 -*-
# @Time    : 18-11-7 下午4:12
# @Author  : Felix Wang
import random
import re
import time
from django.shortcuts import render, redirect
from django.http import JsonResponse
from django.contrib import auth
from django.contrib.auth.models import User
from django.urls import reverse
from django.conf import settings
from .forms import LoginForm, RegisterForm, ForgotPasswordForm, ChangeNicknameForm, BindEmailForm, ChangePasswordForm
from .models import Profile
from myblog.utils import AutoSendEmail


def login(requests):
    # 若是是form表单提交验证登陆
    if requests.method == 'POST':
        login_form = LoginForm(requests.POST)
        if login_form.is_valid():  # 验证是否经过
            # 由于在form表单验证过了,因此不用本身再验证
            user = login_form.cleaned_data.get('user')
            auth.login(requests, user)
            return redirect(requests.GET.get('from', reverse('home')))
        else:
            login_form.add_error(None, '用户名或密码不正确')
    else:
        login_form = LoginForm()
    context = {
        'login_form': login_form,
    }
    return render(requests, 'user/login.html', context)


def login_for_model(requests):
    login_form = LoginForm(requests.POST)

    # 若是是form表单提交验证登陆
    if login_form.is_valid():  # 验证是否经过
        # 由于在form表单验证过了,因此不用本身再验证
        user = login_form.cleaned_data.get('user')
        auth.login(requests, user)

        data = {
            'status': 'SUCCESS',
        }
    else:
        data = {
            'status': 'ERROR',
        }
    return JsonResponse(data)


def register(requests):
    if requests.method == 'POST':
        reg_form = RegisterForm(requests.POST, requests=requests)

        if reg_form.is_valid():
            username = reg_form.cleaned_data['username']
            email = reg_form.cleaned_data['email']
            password = reg_form.cleaned_data['password']

            # 建立用户
            user = User.objects.create_user(username=username, email=email, password=password)
            user.save()

            # 登陆用户
            user = auth.authenticate(username=username, password=password)
            auth.login(requests, user)

            # 注册成功否删除保存的验证码
            del requests.session['register_code']

            # 登陆以后跳转
            return redirect(requests.GET.get('from', reverse('home')))
    else:
        reg_form = RegisterForm()

    context = {
        'reg_form': reg_form,
    }
    return render(requests, 'user/register.html', context)


def logout(requests):
    auth.logout(requests)
    return redirect(requests.GET.get('from', reverse('home')))


def user_info(requests):
    context = {}
    return render(requests, 'user/user_info.html', context)


def change_nickname(requests):
    redirect_to = requests.GET.get('from', reverse('home'))

    if requests.method == 'POST':
        form = ChangeNicknameForm(requests.POST, user=requests.user)
        if form.is_valid():
            nickname_new = form.cleaned_data['nickname_new']
            profile, created = Profile.objects.get_or_create(user=requests.user)
            profile.nickname = nickname_new
            profile.save()
            return redirect(redirect_to)
    else:
        form = ChangeNicknameForm()

    context = {
        'submit_text': '修改',
        'page_title': '修改昵称',
        'form_title': '修改昵称',
        'form': form,
        'return_back_url': redirect_to,

    }
    return render(requests, 'form.html', context)


def bind_email(requests):
    redirect_to = requests.GET.get('from', reverse('home'))

    if requests.method == 'POST':
        form = BindEmailForm(requests.POST, requests=requests)
        if form.is_valid():
            email = form.cleaned_data['email']
            requests.user.email = email
            requests.user.save()

            # 绑定成功后删除验证码
            del requests.session['bind_email_code']
            return redirect(redirect_to)
    else:
        form = BindEmailForm()

    context = {
        'submit_text': '绑定邮箱',
        'page_title': '绑定邮箱',
        'form_title': '绑定',
        'form': form,
        'return_back_url': redirect_to,

    }
    return render(requests, 'user/bind_email.html', context)


def send_verification_code(requests):
    email = requests.GET.get('email', '')
    send_for = requests.GET.get('send_for', '')

    if re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}\.[com,cn,net]{1,3}$', email):
        # 生成验证码
        all_codes = list(range(0x30, 0x39)) + list(range(0x61, 0x74)) + list(range(0x41, 0x5a))  # 大写,小写和数字
        code = ''.join([chr(random.choice(all_codes)) for i in range(6)])
        now = int(time.time())
        send_code_time = requests.session.get('send_code_time', 0)
        if now - send_code_time < 60:
            data = {
                'status': 'ERROR',
            }
        else:
            requests.session[send_for] = code
            requests.session['send_code_time'] = send_code_time
            title = '验证码'
            auto_email = AutoSendEmail(sender=settings.EMAIL_HOST_USER, recever=[email],
                                       password=settings.EMAIL_HOST_PASSWORD, title=title, from_who=settings.FROM_WHO,
                                       smtp_server=settings.MAIL_HOST, port=settings.EMAIL_PORT)
            html = """
                        <html>
                          <head></head>
                          <body>
                            <p>Hi!<br>
                               很是感谢您绑定邮箱!
                               <br>
                               本次的验证码是:{},请不要透露给其余人!
                               <br>
                            </p>
                            <img style="width:180px;height:240px" src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1541440161574&di=fd6156e441788866ffbd6c654d75fa23&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fblog%2F201507%2F22%2F20150722222322_Ky8Nj.jpeg" />
                          </body>
                        </html>
                        """.format(code)

            # 以html的形式发送文字,推荐这个,由于能够添加图片等
            auto_email.addHtml(html)
            # 发送邮件
            try:
                auto_email.sendEmail()
                data = {
                    'status': 'SUCCESS',
                    'msg': '邮件发送成功',
                }
            except Exception as e:
                print(str(e))
                data = {
                    'status': 'ERRORS',
                    'msg': '邮件发送失败',
                }
    else:
        data = {
            'status': 'ERRORS',
            'msg': '邮箱格式不正确',
        }

    return JsonResponse(data)


def change_password(requests):
    redirect_to = reverse('home')

    if requests.method == 'POST':
        form = ChangePasswordForm(requests.POST, user=requests.user)
        if form.is_valid():
            new_password = form.cleaned_data['new_password']
            profile, created = Profile.objects.get_or_create(user=requests.user)
            profile.user.set_password(new_password)
            profile.user.save()
            # 密码修改为功后登出
            auth.logout(requests)
            return redirect(redirect_to)
    else:
        form = ChangePasswordForm()

    context = {
        'submit_text': '修改',
        'page_title': '修改密码',
        'form_title': '修改密码',
        'form': form,
        'return_back_url': redirect_to,

    }
    return render(requests, 'form.html', context)


def forgot_password(requests):
    redirect_to = reverse('login')

    if requests.method == 'POST':
        form = ForgotPasswordForm(requests.POST, requests=requests)
        if form.is_valid():
            email = form.cleaned_data['email']
            new_password = form.cleaned_data['new_password']
            user = User.objects.get(email=email)
            user.set_password(new_password)
            user.save()

            # 绑定成功后删除验证码
            del requests.session['forgot_password_code']
            return redirect(redirect_to)
    else:
        form = ForgotPasswordForm()

    context = {
        'submit_text': '重置密码',
        'page_title': '重置密码',
        'form_title': '重置',
        'form': form,
        'return_back_url': redirect_to,

    }
    return render(requests, 'user/forgot_password.html', context)
views.py
相关文章
相关标签/搜索