第三十二篇,Django的Auth认证系统之用户管理系统

Auth认证系统

Django除了有强大的Admin管理系统之外,还提供了完善的用户管理系统。整个用户管理系统可分为三大部分:用户信息、用户权限和用户组,在数据库中分别对应数据表auth_user、auth_permission和auth_group。

用户管理功能

用户管理功能已经是一个网站必备的功能之一,而Django内置了强大的用户管理系统,并且具有灵活的扩展性,可以满足多方面的开发需求。在创建Django项目时,Django已默认使用内置用户管理系统,在settings.py的INSTALLED_APPS、MIDDLEWARE和AUTH_PASSWORD_VALIDATORS中可以看到相关的配置信息。
本篇使用内置的用户管理系统实现用户的注册、登录、修改密码和注销功能。以MyDjango为例,在项目创建新的App,命名为user,并且在项目的settings.py和urls.py中配置App的信息:

#settings.py配置信息
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
    'user',
    'index.apps.IndexConfig',
    'user.apps.UserConfig',
    'user_defined',
]
#文件夹untitled3的urls.py的URL地址配置

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/',include('index.urls')),
    path('user/',include('user.urls')),
]

在App中分别添加urls.py和user.html文件
在这里插入图片描述
App中的urls.py主要用于接收和处理根目录的urls.py的请求信息。在App的urls.py中设定了4个不同的URL地址,分别代表用户登录、注册、修改密码和用户注销:

#App下的urls.py设置URL地址信息
from django.urls import path
from . import views

urlpatterns = [
    path('login.html', views.loginView, name='login'), #用户登入
    path('register.html', views.registerView, name='register'), #用户注册
    path('setpassword.html', views.setpasswordView, name='setpassword'), #修改密码
    path('logout.html', views.logoutView, name='logout'), #用户注销
]

上述URL地址分别对应视图函数loginView、registerView、setpasswordView、logoutView;参数name用于设置URL的命名,可直接在HTML模板上使用并生成相应的URL地址。首先了解HTML模板的代码结构,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css">
</head>
<body>
<div class="flex-center">
    <div class="container">
    <div class="flex-center">
    <div class="unit-1-2 unit-1-on-mobile">
        <h1>MyDjango Auth</h1>
            {% if tips %}
        <div>{{ tips }}</div>
            {% endif %}
        <form class="form" action="" method="post">
            {% csrf_token %}
            <div>用户名:<input type="text" name='username'></div>
            <div>密 码:<input type="password" name='password'></div>
            {% if new_password %}
                <div>新密码:<input type="password" name='new_password'></div>
            {% endif %}
            <button type="submit" class="btn btn-primary btn-block">确定</button>
        </form>
        <div class="flex-left top-gap text-small">
            <div class="unit-2-3">
                <a href="{{ unit_2 }}">{{ unit_2_name }}</a>
            </div>
            <div class="unit-1-3 flex-right">
                <a href="{{ unit_1 }}">{{ unit_1_name }}</a>
            </div>
        </div>
    </div>
    </div>
    </div>
</div>
</body>
</html>

一个模板分别用于实现用户登录、注册和修改密码,该模板是由两个文本输入框和一个按钮所组成的表单,在该表单下分别设置不同链接,分别指向另外两个URL地址,如下图
在这里插入图片描述
当用户输入账号和密码之后,单击"确定"按钮,就会触发一个POST请求,该请求将表单数据发送到当前的URL地址,再由相应的视图函数进行处理,并将处理结果返回到浏览器上生成相应的网页。
接下来在views.py中实现用户登录功能,视图函数loginView的代码如下:

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth import login, logout, authenticate

# Create your views here.

def loginView(request):
    title = '登录'
    unit_2 = '/user/register.html'
    unit_2_name = '立即注册'
    unit_1 = '/user/setpassword.html'
    unit_1_name = '修改密码'
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if User.objects.filter(username=username):
            user = authenticate(username=username, password=password)
            if user:
                if user.is_active:
                    login(request, user)
                return redirect('/')
            else:
                tips = '账号密码错误,请重新输入'
        else:
            tips = '用户不存在,请注册'
    return render(request, 'user.html', locals())

1、首先设置模板变量title和unit_2等变量值,在模板中生成相关的URL地址,可以从登录界面跳到注册界面或修改密码界面。
2、由于提交表单是由当前的URL执行处理的,因此函数loginView需要处理不同的请求方式。如果是POST请求,则获取表单中两个文本框的数据内容,分别为username和password,然后对模型User中的数据进行判断和验证,只有验证成功之后,网页才会跳转到首页,否则在登录界面上提示错误信息。
3、如果是GET请求,当完成模板变量赋值之后就不再做任何处理,直接将模板user.html生成HTML网页返回到浏览器上。
在整个登录过程中,我们并没有对模型User进行定义,而函数中使用的模型User来自于Django的内置模型,在数据库中对于的数据表为auth_user:
在这里插入图片描述
在这里插入图片描述
Django默认的模型User共定义了11个字段:
在这里插入图片描述
我们结合函数loginView和模型User的字段含义,进一步分析函数loginView的代码功能:
1、当函数loginView收到POST请求并获取表单的数据后,根据表单的数据判断用户是否存在。当用户存在时,对用户的账号和密码进行验证处理,由内置函数authenticate完成验证功能,如果验证成功,函数authenticate返回模型User的数据对象User,否则返回None。
2、然后从对象user的is_active字段来判断当前用户的状态是否被激活,如果为1,说明当前用户处于激活状态,可执行用户登录。
3、最后执行用户登录,由内置函数login完成登录过程。函数login接收两个参数,第一个是request对象,来自视图函数的参数request;第二个是user对象,来自函数authenticate返回的对象user。
从整个登录过程中可以发现,Django为我们提供了完善的内置函数,可快速实现用户登录功能。在index中分别对模板index.html的<header标签和views.py视图函数index进行修改:
在这里插入图片描述

<header id="top">
    <div id="top_box">
        <ul class="lf">
            <li><a href="#">华为官网</a></li>
            <li><a href="#">华为荣耀</a></li>
        </ul>
        <ul class="rt">
            {% if username %}
                <li>用户名: {{ username }}</li>
                <li><a href="{% url 'logout' %}">退出登录</a></li>
            {% else %}
                <li><a href="{% url 'login' %}">登录</a></li>
                <li><a href="{% url 'register' %}">注册</a></li>
            {% endif %}
        </ul>
    </div>
</header>
def index(request):
    #获取当前请求的用户名
    username = request.user.username
    return render(request, 'index.html', locals())

运行项目后,浏览器输入:http://127.0.0.1:8000/user/login.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

用户注册

用户注册的视图函数为registerView,在user的views.py中编写函数registerView:

def registerView(request):
    #设置标题和另外两个URL链接
    title = '注册'
    unit_2 = '/user/login.html'
    unit_2_name = '立即登录'
    unit_1 = '/user/setpassword.html'
    unit_1_name = '修改密码'
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if User.objects.filter(usernam=username):
            tips = '用户已存在'
        else:
            user = User.objects.create_user(username=username,password=password)
            user.save()
            tips = '注册成功,请登录'
    return render(request, 'user.html', locals())

1、当用户输入账号和密码并单击"确定"按钮后,程序将表单数据提交到函数registerView中进行处理。
2、函数registerView首先获取表单的数据内容,根据获取的数据来判断模型User是否存在相关的用户信息。
3、如果用户存在,直接返回到注册界面并提示用户已存在。
4、如果用户不存在,程序使用内置函数create_user对模型User进行用户创建,函数create_user是模型User特有的函数,该函数创建并保存一个is_active=True的User对象。其中,函数参数username不能为空,否则抛出ValueError异常;而模型User的其他字段可作为函数create_user的可选参数,如email、first_name和password等。如果使用过程中没有设置函数参数password,则User对象的set_unusable_password()函数将会被调用,为当前用户创建一个随机密码。

修改密码

在views.py中变成函数setpasswordView,实现修改用户密码的功能:

def setpasswordView(request):
    #设置标题和另外两个URL链接
    title = '修改密码'
    unit_2 = '/user/login.html'
    unit_2_name = '立即登录'
    unit_1 = '/user/register.html'
    unit_1_name = '立即注册'
    new_password = True
    if request.method == 'POST':
        username = request.POST.get('username', '')
        old_password = request.POST.get('new_password', '')
        new_password = request.POST.get('new_password', '')
        if User.objects.filter(username=username):
            user = authenticate(username=username, password=old_password)
            user.set_password(new_password)
            user.save()
            tips = '密码修改成功'
        else:
            tips = '用户不存在'
    return render(request, 'user.html', locals())

密码修改界面相比注册和登录界面多出了一个文本输入框,该文本输入框由模板变量new_password控制显示。当变量new_password为True时,文本输入框将显示到页面上。
在这里插入图片描述
1、当函数setpasswordView收到表单提交的请求后,程序会获取表单的数据内容,然后根据表单数据查找模型User相应的数据。
2、如果用户存在,由内置函数authenticate验证用户的账号和密码是否正确,若验证成功,则返回user对象,再使用内置函数set_password修改对象user的密码,最后保存修改后的user对象,从而实现密码修改。
3、如果用户不存在,直接返回到界面并提示用户不存在。
 密码修改主要由内置函数set_password实现,而函数set_password是在内置函数make_password的基础上进行封装而来的。我们知道在默认情况下,Django使用pbkdf2_sha256方式来存储和管理用户密码,而内置函数make_password主要实现用户密码的加密功能,并且该函数可以脱离Auth认证系统单独使用,比如对某些特殊数据进行加密处理等,在上述例子中也可以使用函数make_password实现密码修改:

#使用make_password实现密码修改
def setpasswordView_1(request):
    if request.method == 'POST':
        username = request.POST.get('username', '')
        old_password = request.POST.get('password', '')
        new_password = request.POST.get('new_password', '')
        #判断用户是否存在
        user = User.objects.filter(username=username)
        if User.objects.filter(username=username):
            user = authenticate(username=username,password=old_password)
            #密码加密处理并保存到数据库
            dj_ps = make_password(new_password, None, 'pbkdf2_sha256')
            user.password = dj_ps
            user.save()
    return render(request, 'user.html', locals())

除了内置函数make_password处,还有内置函数check_password,该函数是对加密前的密码与加密后的密码进行验证匹配,判断两者是否为同一个密码。在PyCharm的Terminal中开启Django的shell模式,函数make_password和check_password的使用方法如下:
在这里插入图片描述

用户注销

用户注销是用户管理系统较为简单的功能,调用内置函数logout即可实现。函数logout接收参数request,代表当前用户的请求对象,来自于视图函数的参数request,直接让它回到登录界面就欧克了因此,视图函数logoutView的代码如下:

def logoutView(request):
    logout(request)
    # 设置标题和另外两个URL链接
    title = '登入'
    unit_2 = '/user/login.html'
    unit_2_name = '立即登录'
    unit_1 = '/user/register.html'
    unit_1_name = '立即注册'
    if request.method == 'POST':
        username = request.POST.get('username', '')
        password = request.POST.get('password', '')
        if User.objects.filter(username=username):
            user = authenticate(username=username, password=password)
            if user:
                if user.is_active:
                    login(request, user)
                return redirect('/')
            else:
                tips = '账号密码错误,请重新输入'
        else:
            tips = '用户不存在,请注册'
    return render(request, 'user.html', locals())
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值