• Python + Django4 搭建个人博客(十四):实现用户登录和登出功能


    本篇开始我们来实现用户管理模块。

    首先我们来实现一下用户的登录和登出。

    创建APP

    用户和文章属于不同的功能模块,为了方便管理,我们新建一个名为userprofileApp

    运行startapp指令创建新的app:

    python manage.py startapp userprofile

    可以看到我们已经生成了一个新的App

    将App添加到App列表:

    1. INSTALLED_APPS = [
    2. 'django.contrib.admin',
    3. 'django.contrib.auth',
    4. 'django.contrib.contenttypes',
    5. 'django.contrib.sessions',
    6. 'django.contrib.messages',
    7. 'django.contrib.staticfiles',
    8. 'article',
    9. # 新增'userprofile'代码,激活app
    10. 'userprofile',
    11. ]

    编写登录表单

    用户登录时,需要填写账户密码等表单数据,因此又要用到Form表单类。

    之前在创建文章的时候我们介绍了,Django表单,当时我们使用了forms.ModelForm的继承类,这次我们再使用另外一个类:forms.Form

    userprofile目录中创建表单类的文件forms.py,编写如下代码:

    1. # 引入表单类
    2. from django import forms
    3. # 登录表单,继承了 forms.Form 类
    4. class UserLoginForm(forms.Form):
    5. username = forms.CharField()
    6. password = forms.CharField()

    forms.ModelForm,这个父类适合于需要直接与数据库交互的功能。

    forms.Form需要手动配置每个字段,它适用于不与数据库进行直接交互的功能。用户登录不需要对数据库进行任何改动,因此直接继承forms.Form就可以了。

    编写视图

    常规的App我们在编写视图之前还需要编写模型,但是在Django框架下,我们在创建项目的时候Django已经自动帮我们创建了一个用户模型。

    实际上我们在使用Admin模块的时候已经用到了。

    我们在实现用户功能的时候可以直接使用Django内置的User模型,针对自带User模型Django内部也集成了一些常见的视图函数,比如登录,登出,会话管理等,可以极大的提示我们的Web开发效率。

    登录视图

    userprofile/views.py中写视图函数:

    1. from django.shortcuts import render, redirect
    2. from django.contrib.auth import authenticate, login
    3. from django.http import HttpResponse
    4. from .forms import UserLoginForm
    5. # Create your views here.
    6. def user_login(request):
    7. if request.method == 'POST':
    8. user_login_form = UserLoginForm(data=request.POST)
    9. if user_login_form.is_valid():
    10. # .cleaned_data 清洗出合法数据
    11. data = user_login_form.cleaned_data
    12. # 检验账号、密码是否正确匹配数据库中的某个用户
    13. # 如果均匹配则返回这个 user 对象
    14. user = authenticate(username=data['username'], password=data['password'])
    15. if user:
    16. # 将用户数据保存在 session 中,即实现了登录动作
    17. login(request, user)
    18. return redirect("list")
    19. else:
    20. return HttpResponse("账号或密码输入有误。请重新输入~")
    21. else:
    22. return HttpResponse("账号或密码输入不合法")
    23. elif request.method == 'GET':
    24. user_login_form = UserLoginForm()
    25. context = { 'form': user_login_form }
    26. return render(request, 'userprofile/login.html', context)
    27. else:
    28. return HttpResponse("请使用GET或POST请求数据")

    这里我们引入了Django自带的authenticate, login模块,用来实现用户验证和登录功能。

    • 跟发表文章的表单类类似,Form对象的主要任务就是验证数据。调用is_valid()方法验证并返回指定数据是否有效的布尔值。
    • Form不仅负责验证数据,还可以“清洗”它:将其标准化为一致的格式,这个特性使得它允许以各种方式输入特定字段的数据,并且始终产生一致的输出。一旦Form使用数据创建了一个实例并对其进行了验证,就可以通过cleaned_data属性访问清洗之后的数据。
    • authenticate()方法验证用户名称和密码是否匹配,如果是,则将这个用户数据返回。
    • login()方法实现用户登录,将用户数据保存在session中。

    Session在网络应用中,称为“会话控制”,它存储特定用户会话所需的属性及配置信息。

    当用户在 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

    Session 最常见的用法就是存储用户的登录数据。

    登出视图

    登出视图更加简单,引入logout模块直接调用自带的logout()函数,所有的Web相关动作Django后台都做完了。

    1. # 用户退出
    2. def user_logout(request):
    3. logout(request)
    4. return redirect("list")

    编写模板

    这里我们改两个地方:

    1.增加导航栏入口:

    改写一下tempalates/header.html,把登录和登出的按钮加进去:

    1. ...
    2. class="nav-item">
  • #增加以下内容
  • {% if user.is_authenticated %}
  • class="nav-item dropdown">
    • class="dropdown-menu">
  • {% else %}
  • class="nav-item">
  • {% endif %}
  • 这里使用了新的模板语法:{% if ... %},用来判断用户是否已经登录:

    is_authenticatedmodels.User类的属性,用于判断用户是否已通过身份验证。

    2.新建登录页面

    新建文件夹templates/userprofile,然后再文件夹内新增login.html

    1. {% extends "base.html" %} {% load static %}
    2. {% block title %} 登录 {% endblock title %}
    3. {% block content %}
    4. <div class="container">
    5. <div class="row">
    6. <div class="col-12">
    7. <br>
    8. <form method="post" action=".">
    9. {% csrf_token %}
    10. <div class="form-group">
    11. <label for="username">账号label>
    12. <input type="text" class="form-control" id="username" name="username">
    13. div>
    14. <div class="form-group">
    15. <label for="password">密码label>
    16. <input type="password" class="form-control" id="password" name="password">
    17. div>
    18. <button type="submit" class="btn btn-primary">提交button>
    19. form>
    20. div>
    21. div>
    22. div>
    23. {% endblock content %}

    改写URL

    在url.py 文件中引入userprofile的视图,并添加用户管理的url路由地址。

    1. from django.contrib import admin
    2. from django.urls import path, re_path
    3. # 引入app视图
    4. import article.views
    5. import userprofile.views
    6. urlpatterns = [
    7. path('admin/', admin.site.urls),
    8. path('hello/', article.views.hello),
    9. re_path(r'^$', article.views.article_list),
    10. path('list/', article.views.article_list, name='list'), # 展示文章
    11. path('detail//', article.views.article_detail, name='detail'), # 文章详情
    12. path('create/', article.views.article_create, name='create'), # 写文章
    13. path('delete//', article.views.article_delete, name='delete'),# 删除文章
    14. path('update//', article.views.article_update, name='update'), # 更新文章
    15. # 增加用户管理
    16. path('login/', userprofile.views.user_login, name='login' ),
    17. path('logout/', userprofile.views.user_logout, name='logout' ),
    18. ]

    因为userprofile这个app并没有改动model,因此我们不用迁移数据。

    运行服务器,打开博客网址,如果我们之前使用超级用户admin登录过,则会直接显示我们已登录超级用户信息:

    在用户下拉菜单中点击退出登录,网址将会出现登录按钮:

    点击登录按钮

    输入用户名和密码后,点击登录按钮,登录成功,显示我们的用户名:

    至此,我们已经完整的实现了用户的登录和登出功能。

    结语

    本篇,我们利用Django内置的User模型,并调用了内置的loginlogout等功能函数实现了一个Web网站的登录和登出功能。

    在模板中使用的Django模板的{% if ... %}语法,实现了根据不同的条件显示不同内容。

    下篇我们继续实现用户管理相关的功能:用户注册。

  • 相关阅读:
    Nginx 服务器 SSL 证书安装部署
    git初次使用
    Linux易混淆知识点
    SpringBootCMS漏洞复现分析
    Windows下SpringBoot连接Redis的正确使用姿势
    电量优化 - Hook 系统服务
    这样做时间轴,让你的PPT更出彩!
    Win10系统下提示“系统组策略禁止安装此设备”的解决方案(家庭版无组策略)
    在ubuntu上安装ns2和nam(ubuntu16.04)
    [JavaWeb基础(三)]HTTP请求消息与登录案例分析
  • 原文地址:https://blog.csdn.net/agelee/article/details/126937900