Django的注册登录界面设计与实现

先实现注册界面的渲染。

创建文件如下:

进入settings.py 进行如下设置:

1.注册app

2.设置templates的文件夹路径

3.设置static文件的路径

STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static')
]

在myApp中的urls.py文件所起的作用是进行url的拼接。

在views.py文件中返回一个界面的时候,myApp中的urls.py和myPro中的urls.py文件进行路由的传输:

视图文件views.py文件中的代码如下:

from django.shortcuts import render
from django.views import View
# Create your views here.


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

在myApp文件中添加如下代码:

from django.urls import path
from .views import RegisterView

urlpatterns = [
    path(r'register/',RegisterView.as_view(),name = 'register'),
]

myPro中的urls.py文件中代码如下:

from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/',include('myApp.urls')),
]

最后来到register.html文件中进行界面的设置,代码如下:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="/static/css/bootstrap.css">
    <title>注册</title>
</head>
<body>
  <div class="container">
        <h2 class="text-center">请输入注册信息</h2>
        <form class="form-horizontal" role="form" action="{% url 'register' %}" method="POST">
            {% csrf_token %}

            <div class="form-group">
                <label for="inputEmail" class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-10">
                  <input name="email" type="text" class="form-control" id="inputEmail" placeholder="请输入邮箱">
                </div>
            </div>
            <div class="form-group">
                <label for="inputPassword" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                  <input name="password" type="text" class="form-control" id="inputPassword" placeholder="请输入密码">
                </div>
            </div>

            <div class="form-group" id="right">
                <div class="col-sm-10">
                    {{register_form.captcha}}
                    <label for="" id="show"></label>
                </div>
            </div>

            <div class="form-group">
                <h3>{{register_form.errors.email}}</h3>
                <h3>{{register_form.errors.password}}</h3>
                <h3>{{register_form.errors.captcha}}</h3>
                <h3>{{msg}}</h3>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                  <button id="submit" type="submit" class="btn btn-default btn-block btn-success">注册</button>
                </div>
            </div>
        </form>
    </div>
  <script src="/static/js/jquery.js"></script>
  <script src="static/js/bootstrap.js"></script>
</body>
</html>

此时启动之后,网址url为:http://localhost:8000/login/register/

显示的界面如下:

此时,我们需要做的工作即是:需要在界面上添加一个验证码,并且当填写输入信息的时候,对信息做判断处理。

我们需要在myApp文件中新建一个forms.py文件,里面创建我们的账号密码以及验证码的类。代码如下:

from django import forms
from captcha.fields import CaptchaField


class RegisterForm(forms.Form):
    email = forms.EmailField(required=True,error_messages={'invalid':"邮箱格式不正确"})
    password = forms.CharField(min_length=6,required=True,error_messages={'min_length':"密码长度不够"})
    captcha = CaptchaField(required=True,error_messages={'invalid':"验证码错误"})

然后在views.py文件中进行调用即可,代码如下:

register_form = RegisterForm()

接下来就是处理关于验证码的错误的时候了。

1.

RuntimeError: Model class captcha.models.CaptchaStore doesn't declare anexplicit app_label and isn't in an application in INSTALLED_APPS.

这个错误提示我们需要在settings.py文件中进行注册:

2.在项目里面urls进行设置
Make sure you\'ve included captcha.urls a
s explained in the INSTALLATION section on http://readthedocs.org/docs/django-simple-captcha/en/latest/usage.html#installation'
代码如下:
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('login/',include('myApp.urls')),
    path('captcha/',include('captcha.urls')),
]

3.no such table
重新模型迁移

在模型文件models.py文件中创建字段。代码如下:

from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

# 模型一旦发生改变,要重新迁移
class UserProfile(AbstractUser):
    unickname = models.CharField(max_length=20,verbose_name='昵称',null=True,blank=True)
    ubirthday = models.DateField(auto_now_add=True,verbose_name='生日',null=True)
    uaddress = models.CharField(max_length=200,verbose_name='地址')

当迁移文件遇到下面错误的时候:

HINT: Add or change a related_name argument to the definition for 'UserProf
ile.user_permissions' or 'User.user_permissions'.
是因为设置文件缺少了一句这样的设置:

AUTH_USER_MODEL = 'myApp.UserProfile'

设置完毕之后,我们需要将验证码生成在界面上,来到register.html文件中,对验证码做接收即可:

<div class="form-group" id="right">
    <div class="col-sm-10">
        {{register_form.captcha}}
        <label for="" id="show"></label>
    </div>
</div>

此时刷新界面,可以得到如下的结果:

接下来我们要做的工作就是,当我们刷新验证码的时候,也就是我们鼠标点击验证码的时候,验证码会刷新,当我们鼠标放在验证码上时,鼠标的形状会改变。并且验证码需要一定的时间显示提示用户输入,此时需要在验证码的图片上添加一个点击事件,代码如下:

 <script>
       $(function () {
//           设置鼠标放在验证码上,更换鼠标的形状
            $('.captcha').css('cursor','pointer')
            $('.captcha').click(function () {
                showNewCode()
            })
        })
      function  showNewCode(){
            oldValue = false
            seconds = 3
            timeInterval = null
//         请求验证码地址,获取最新的验证码图片以及验证码内容
             $.getJSON('/captcha/refresh/',function (data) {
                    console.log(data)
//                    attribute属性
//                    更新验证码图片
                    $('.captcha').attr('src',data['image_url'])
//                    更新验证码的值
                    $('#id_captcha_0').val(data['key'])
                  timeInterval = setInterval(function () {
                        seconds --
                        $('#show').text(seconds + 's')
                        if(seconds<0)
                        {
                            clearInterval(timeInterval)
                            oldValue = true
                            $('#show').text('')
                        }
                    },1000)
                })
        }
$('#id_captcha_1').click(function () {
    if(oldValue == true)
    {
        alert('验证码已过期')
        showNewCode()
    }
})

  </script>

此时的结果如下:

这样,我们就完成了注册界面的设置,下面就是当用户注册的时候,我们需要将数据存储到数据库。然后在用户登录的时候,拿出来对比,若数据一样,那就可以登录成功,若数据不一样,则登录失败。

此时的views.py中注册代码如下:

from django.shortcuts import render
from django.views import View
from .forms import RegisterForm
from .models import UserProfile
from django.contrib.auth.hashers import make_password
class RegisterView(View):
    def get(self,request):
        # 创建实例化对象
        register_form = RegisterForm()

        return render(request,'register.html',{'register_form':register_form})

    def post(self,request):
        register_form = RegisterForm(request.POST)
        if register_form.is_valid():
            # 从请求中获取email的值
            email = request.POST['email']
            # 从请求中获取password的值
            password = request.POST['password']
            # 判断是否有相同的账号在数据库中
            user = UserProfile.objects.filter(email=email)

            if user:
                # 相同的话,注册失败,返回注册界面,同时返回注册失败的信息
                return render(request,'register.html',{'register_form':register_form})

            user = UserProfile()
            user.email = email
            # 利用哈希算法加密注册密码
            user.password = make_password(password)
            user.is_active = 0
            user.save()
            # send_email(email = email)

            return render(request,'tips.html')
        else:
            # 数据不合法
            return render(request,'register.html',{'register_form':register_form})

tips.html文件中跳转界面的设置代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册成功的界面</title>
</head>
<body>
    <div>
        <span>
            3
        </span>
        秒钟以后跳转到其他页面
    </div>
    <a href="/login/login/">立即跳转</a>
    <script src="/static/js/jquery.js"></script>
    <script>
//        设置3秒钟之后自动跳转界面
        $(function () {
            var second = 3
            setInterval(function () {
                second --;
                $('span').text(second + 's')
                if (second == 0)
                {
                    window.location.href = '/login/login/'
                }
            },1000)
        })
    </script>


</body>
</html>

界面显示结果如下:

此时界面需要跳转到登录界面,我们需要在myApp文件中的urls.py文件中做路由设置,代码如下:

from django.urls import path
from .views import RegisterView,LoginView

urlpatterns = [
    path(r'register/',RegisterView.as_view(),name = 'register'),
    path(r'login/',LoginView.as_view(),name='login'),
]

然后在views.py文件中做界面返回处理,代码如下:

class LoginView(View):
    def get(self,request):
        return render(request,'login.html')
    def post(self,request):
        return render(request,'login.html')

新建login.html文件,这个界面即为我们的登陆界面。稍后再做处理。

此时我们完成了注册界面的跳转,还有很重要的一部分,即为我们在点击注册按钮,跳转界面的时候,我们想要实现一个自动给注册者的邮箱发送一封验证邮件,该怎么做处理呢?

首先,我们需要做一个发送邮件的设置,来到settings文件中,设置如下:

# 邮箱设置
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT =25
EMAIL_HOST_USER = 'xxxxxxxx'
EMAIL_HOST_PASSWORD ='xxxx'
# 开启安全连接
EMAIL_HOST_TLS = True

然后新建一个发送邮件的文件夹,如下:

代码如下:

from django.core.mail import send_mail,EmailMultiAlternatives
from django.conf import settings
import random
from myApp.models import EmailRecord

def get_random_code(max_length=16):
    str = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'
    content = ''
    for x in range(max_length):
        content = content + random.choice(str)
        # content = content +random.randint(0,len(str)-1)
    return content

def send_email(code,email):
    if code==0 or code==None:
        code = get_random_code()

    # 获取随机的激活码
    code = get_random_code()
    # 保存邮件信息
    email_obj = EmailRecord()
    email_obj.code = code
    email_obj.email = email
    email_obj.save()

    email_subject = 'XX网账户激活通知'
    mail_content = '<h3>点击以下链接,激活账户:</h3><a href="http://localhost:8000/login/active/%s">http://localhost:8000/login/active/%s</a> '%(code,code)

    mail = EmailMultiAlternatives(email_subject,mail_content,settings.EMAIL_HOST_USER,['[email protected]',])

    mail.content_subtype = 'html'
    res = mail.send()
    return res

然后将上面注册部分的那句

send_email(email = email)

解注释即可。

在发送邮箱之后,用户点击邮箱中的验证链接应该跳转到另一个页面,我们在models.py文件中做这样的设置:

class EmailRecord(models.Model):

    code = models.CharField(max_length=20,)
    send_date = models.DateTimeField(default = datetime.datetime.now(),)
    email = models.EmailField(error_messages={'invalid':'邮箱格式'},)

接下来,我们进行登录界面的设置。

模板代码如下:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% block link %}
    {% endblock %}
    <link rel="stylesheet" href="/static/css/bootstrap.css">
    <title>{% block title %}注册{% endblock %}</title>
   {% block style %}
     <style>
        .container{
            margin-top: 60px;
        }
        .form-horizontal{
            position: relative;
            left: -8%;
        }
        .captcha{
            width: 80px;
            height: 40px;
        }
        #right{
            position: relative;
            left: 200px;
            color: gray;
        }
    </style>
    {% endblock %}
</head>
<body>
   {% block main %}
    <div class="container">
        <h2 class="text-center">请输入注册信息</h2>
        <form class="form-horizontal" role="form" action="{% url 'register' %}" method="POST">
            {% csrf_token %}

            <div class="form-group">
                <label for="inputEmail" class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-10">
                  <input name="email" type="text" class="form-control" id="inputEmail" placeholder="请输入邮箱">
                </div>
            </div>
            <div class="form-group">
                <label for="inputPassword" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                  <input name="password" type="text" class="form-control" id="inputPassword" placeholder="请输入密码">
                </div>
            </div>

            <div class="form-group" id="right">
                <div class="col-sm-10">
                    {{register_form.captcha}}
                    <label for="" id="show"></label>
                </div>
            </div>

            <div class="form-group">
                <h3>{{register_form.errors.email}}</h3>
                <h3>{{register_form.errors.password}}</h3>
                <h3>{{register_form.errors.captcha}}</h3>
                <h3>{{msg}}</h3>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                  <button id="submit" type="submit" class="btn btn-default btn-block btn-success">注册</button>
                </div>
            </div>
        </form>
    </div>
   {% endblock %}
    <script src="/static/js/jquery.js"></script>
    <script src="/static/js/bootstrap.js"></script>
    {% block script %}
   <script>
        $(function () {
            $('.captcha').css('cursor','pointer')
            $('.captcha').click(function () {
                showNewCode()
            })
        })

        function  showNewCode(){
            oldValue = false
            seconds = 3
            timeInterval = null
//         请求验证码地址,获取最新的验证码图片以及验证码内容
             $.getJSON('/captcha/refresh/',function (data) {
                    console.log(data)
//                    attribute属性
//                    更新验证码图片
                    $('.captcha').attr('src',data['image_url'])
//                    更新验证码的值
                    $('#id_captcha_0').val(data['key'])

                    timeInterval = setInterval(function () {
                        seconds --
                        $('#show').text(seconds + 's')
                        if(seconds<0)
                        {
                            clearInterval(timeInterval)
                            oldValue = true
                            $('#show').text('')
                        }
                    },1000)
                })
        }

        $('#id_captcha_1').click(function () {
            if(oldValue == true)
            {
                alert('验证码已过期')
                showNewCode()
            }
        })
    </script>
    {% endblock %}

</body>
</html>

登录界面继承自母模板,代码如下:

{% extends 'base.html' %}

{% block main %}
<div class="container">
        <h2 class="text-center">请输入登录信息</h2>
        <form class="form-horizontal" role="form" action="{% url 'login' %}" method="POST">
            {% csrf_token %}

            <div class="form-group">
                <label for="inputEmail" class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-10">
                  <input name="email" type="text" class="form-control" id="inputEmail" placeholder="请输入邮箱">
                </div>
            </div>

            <div class="form-group">
                <label for="inputPassword" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                  <input name="password" type="text" class="form-control" id="inputPassword" placeholder="请输入密码">
                </div>
            </div>

            <div class="form-group">
                <h3>{{register_form.errors.email}}</h3>
                <h3>{{register_form.errors.password}}</h3>
                <h3>{{msg}}</h3>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                  <button id="submit" type="submit" class="btn btn-default btn-block btn-success">登录</button>
                </div>
            </div>
        </form>
    </div>
{% endblock %}

报错信息:

UNIQUE constraint failed: myApp_userprofile.username

当我们第二次注册的时候,会报这个错误,这时,需要在注册的函数中添加这样一句话:

user.username = email

即可以解决这个问题。

刷新登录界面,如图:

在登录的时候,我们需要通过forms来验证对照输入的账号和密码,在forms.py文件中做如下设置:

class LoginForm(forms.Form):
    email = forms.EmailField(required=True,error_messages={'invalid':'邮箱格式不正确'})
    password = forms.CharField(min_length=6,required=True,error_messages={'min_length':'密码长度少于6'})

重新迁移文件。

即可完成邮件发送功能。

然后在视图文件中写登录代码:

class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')
    def post(self,request):
        login_form = LoginForm(request.POST)
        if login_form.is_valid():
            email = request.POST['email']
            password = request.POST['password']

            # user = UserProfile.objects.get(email=email)
            # 验证账号密码是否一致
            # user = authenticate(email=email,password=password)
            user = UserProfile.objects.get(email=email)
            result = check_password(password,user.password)
            if result:
                if user.is_active == 1:
                    return render(request,'home.html')
                else:
                    code_obj = EmailRecord.objects.get(email=email)
                    code = code_obj.code
                    send_email(email,code)
                    return render(request,'login.html',{'login_form':login_form,'msg':'该账号尚未被激活,请前往邮箱进行激活'})
            else:
                return render(request,'login.html',{'login_form':login_form,'msg':'账号密码不匹配,请核对'})
        else:
            return render(request,'login.html',{'login_form':login_form})

最后剩下一个激活码激活跳转到登录页面的功能。

视图文件代码如下:

class ActiveView(View):

    def get(self,request,code):
        try:
            # 根据指定的激活码,找到对应的邮箱
            email_code = EmailRecord.objects.get(code=code)
        except Exception as e:
            # 如果邮箱没有被找到,
            return render(request,'activefile.html')
        else:
            # 如果邮箱被找到
            user = UserProfile.objects.get(email=email_code.email)
            user.is_active = 1
            user.save()
            return render(request,'login.html')

    def post(self,request,code):
        return render(request,'page.html')

myApp中路由设置为:

from django.conf.urls import url

urlpatterns = [
    url(r'active/(?P<code>\w+)/', ActiveView.as_view(), name='active')
]

此时,我们就完成了所有的功能。

猜你喜欢

转载自blog.csdn.net/qq_39138295/article/details/82762940