欢迎来到Felix的博客

Do the right things! And talk is cheap,show me your code!

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

1、修改的部分

 

2、上代码

{% 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

 

posted @ 2018-11-30 10:43  寂静的天空  阅读(264)  评论(0编辑  收藏  举报
个人感悟: 一个人最好的镜子就是自己,你眼中的你和别人眼中的你,不是一回事。有人夸你,别信;有人骂你,别听。一根稻草,扔街上就是垃圾;捆上白菜就是白菜价;捆上大闸蟹就是大闸蟹的价。 一个人,不狂是没有出息的,但一直狂,肯定是没有出息的。雨打残花风卷流云,剑影刀光闪过后,你满脸冷酷的站在珠峰顶端,傲视苍生无比英武,此时我问你:你怎么下去? 改变自己就是改变自己的心态,该沉的时候沉下去,该浮的时候浮上来;不争名夺利,不投机取巧,不尔虞我诈;少说、多听、多行动。人每所谓穷通寿夭为命所系,岂不知造物之报施,全视人之自取。 座佑铭:每一个不曾起舞的日子,都是对生命的辜负。