Django教程第3章 | Web开发实战-登录

简介: 登录案例、Djiango中间件【2月更文挑战第23天】

 专栏系列:Django学习教程

前言

目标:实现用户登录和验证码功能。

知识点:表单验证、错误提示、DjangoAuth统一认证、验证码

效果图

image.gif 编辑

image.gif 编辑

 

Django cookie 与 session

Cookie 是存储在客户端计算机上的文本文件,并保留了各种跟踪信息。

识别返回用户包括三个步骤:

  • 服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。
  • 浏览器将这些信息存储在本地计算机上,以备将来使用。
  • 当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。

HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:

Cookies

一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别。

在Web开发中,使用 session 来完成会话跟踪,session 底层依赖 Cookie 技术。

image.gif 编辑

image.gif 编辑

代码案例

1.编写模板HTML

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户管理系统</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .account {
            width: 400px;
            border: 1px solid #dddddd;
            border-radius: 5px;
            box-shadow: 5px 5px 20px #aaa;
            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }
        .account h2 {
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>
<body>
<div class="account">
    <h2>用户登录</h2>
    <form method="post" novalidate>
        {% csrf_token %}
        <div class="form-group">
            <label>用户名</label>
            {{ form.username }}
            <span style="color: red;">{{ form.username.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label>密码</label>
            {{ form.password }}
            <span style="color: red;">{{ form.password.errors.0 }}</span>
        </div>
        <div class="form-group">
            <label for="id_code">图片验证码</label>
            <div class="row">
                <div class="col-xs-7">
                    {{ form.code }}
                    <span style="color: red;">{{ form.code.errors.0 }}</span>
                </div>
                <div class="col-xs-5">
                    <img id="image_code" src="/image/code/" onclick="changeImg(this)" style="width: 125px;" />
                </div>
            </div>
        </div>
        <input type="submit" value="登 录" class="btn btn-primary">
    </form>
</div>
</body>
<script>
    function changeImg(ths) {
        // 硬编码
        ths.src = '/image/code/?temp=' + Math.random();
    }
</script>
</html>

image.gif

2.编写模型

from django.db import models
class UserInfo(models.Model):
    username = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    age = models.IntegerField(verbose_name='年龄')
    salary = models.DecimalField(verbose_name='工资', max_digits=10, decimal_places=2)
    gender_choices =(
        (1, '男'),
        (2, '女')
    )
    gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices)
    create_time = models.DateTimeField(verbose_name='创建时间')
    # dept_id = models.ForeignKey(to=Department, to_field='id', null=True, blank=True, on_delete=models.SET_NULL)
    dept = models.ForeignKey(verbose_name="部门", to='Department', to_field="id", on_delete=models.CASCADE)

image.gif

3.编写视图函数

login函数:校验验证码--》验证用户名密码是否正确--》设置用户过期时间为30分钟--》跳转到首页

image.gif 编辑

登录逻辑图

image_code函数:调用check_code(),生成验证码,设置session60过期。

logout函数:退出登录,删除服务器存储的session并跳转到登陆页面。

views.py

def login(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request, 'login.html', {'form': form})
    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 验证码的校验
        user_input_code = form.cleaned_data.pop('code')
        code = request.session.get('image_code', "")
        if code.upper() != user_input_code.upper():
            form.add_error("code", "验证码错误")
            return render(request, 'login.html', {'form': form})
        # 查询数据库匹配用户名密码是否正确
        user_obj = models.UserInfo.objects.filter(**form.cleaned_data).first()
        print(user_obj)
        if not user_obj:
            form.add_error('password', '用户名或密码错误')
            return render(request, 'login.html', {'form': form})
        request.session['info'] = {'id': user_obj.id, 'username': user_obj.username}
        # 设置 session 过期时间为30分钟
        request.session.set_expiry(60 * 30)
        return redirect('/user/list/')
    return render(request, 'login.html', {'form': form})
def image_code(request):
    """ 生成图片验证码 """
    # 调用pillow函数,生成图片
    img, code_string = check_code()
    # 写入到自己的session中(以便于后续获取验证码再进行校验)
    request.session['image_code'] = code_string
    # 给Session设置60s超时
    request.session.set_expiry(60)
    stream = BytesIO()
    img.save(stream, 'png')
    return HttpResponse(stream.getvalue())
def logout(request):
    request.session.flush()
    return redirect('/login/')
class LoginForm(BootstrapForm):
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput,
        required=True
    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),
        required=True,
    )
    code = forms.CharField(
        label="验证码",
        widget=forms.TextInput,
        required=True
    )

image.gif

4.编写统一过滤(AuthMiddleware)

1.排除那些不需要登录就能访问的页面,例如:login请求,验证码请求

2.读取当前访问的用户的session信息,如果能读到,说明已登陆过,可以访问系统。

3.没有登陆过,也就是在访问系统在浏览器没有用户cookie或者已经失效,则跳转到登陆页面。

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
class AuthMiddleware(MiddlewareMixin):
    def process_request(self, request):
        # 0.排除那些不需要登录就能访问的页面
        #   request.path_info 获取当前用户请求的URL /login/
        if request.path_info in ["/login/", "/image/code/"]:
            return
        # 1.读取当前访问的用户的session信息,如果能读到,说明已登陆过,就可以继续向后走。
        info_dict = request.session.get("info")
        # print(info_dict)
        if info_dict:
            return
        # 2.没有登录过,重新回到登录页面
        return redirect("/login/")

image.gif

然后在settings.py配置中间件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'ums.middleware.auth.AuthMiddleware',    # 新增位置
]

image.gif

5.配置路由

from django.urls import path
from ums.views import auth
path('user/<int:nid>/edit_user_password/', auth.edit_user_password),
path('login/', auth.login),
path('logout/', auth.logout),
path('image/code/', auth.image_code),

image.gif

本篇中我使用的是手动绘制验证码,大家可以尝试基于下一章将手动验证码换成自动验证码或者滑动验证码。

如果本文对你有帮助,记得点赞关注,你的支持是我最大的动力!

下一章:Django教程-三种验证码实现-CSDN博客


相关文章
|
1月前
|
前端开发 关系型数据库 测试技术
django集成pytest进行自动化单元测试实战
在Django项目中集成Pytest进行单元测试可以提高测试的灵活性和效率,相比于Django自带的测试框架,Pytest提供了更为丰富和强大的测试功能。本文通过一个实际项目ishareblog介绍django集成pytest进行自动化单元测试实战。
26 3
django集成pytest进行自动化单元测试实战
|
16天前
|
Java API Apache
从零到英雄的蜕变:如何用Apache Wicket打造你的第一个Web应用——不仅是教程,更是编程之旅的启航
【9月更文挑战第4天】学习Apache Wicket这一开源Java Web应用框架是一段激动人心的旅程。本文将指导你通过Maven搭建环境,并创建首个“Hello, World!”应用。从配置`pom.xml`到实现`HelloWorldApplication`类,再到`web.xml`的设置,一步步教你构建与部署简单网页。适合初学者快速上手,体验其简洁API与强大组件化设计的魅力。
14 1
|
1月前
|
数据库 开发者 Python
Python网络编程:Web框架基础(Flask/Django)
Python作为一种功能强大且易于使用的编程语言,广泛应用于Web开发领域。Python的丰富生态系统中,有两个非常流行的Web框架:Flask和Django。本博文将详细介绍这两个框架的基础知识,并通过综合示例展示如何使用它们构建Web应用。
|
1月前
|
运维 Devops 测试技术
一个人活成一个团队:python的django项目devops实战
DevOps通过自动化的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠。本文通过一个python的django个人博客应用进行了DevOps的实战,通过DevOps拉通开发和运维,通过应用云效的DevOps平台实现自动化“软件交付”的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠,提交研发交付效率。作为个人项目也是可以应用devops提高效率。
36 3
|
1月前
|
开发框架 .NET API
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
在IIS上部署ASP.NET Core Web API和Blazor Wasm详细教程
123 3
|
1月前
|
SQL 前端开发 关系型数据库
Python之Web框架Django
Python之Web框架Django
15 0
|
1月前
|
设计模式 API Python
Python Web:Django、Flask和FastAPI框架对比
Python Web:Django、Flask和FastAPI框架对比
46 0
|
19天前
|
数据库 开发者 Python
web应用开发
【9月更文挑战第1天】web应用开发
34 1
|
7天前
|
数据可视化 图形学 UED
只需四步,轻松开发三维模型Web应用
为了让用户更方便地应用三维模型,阿里云DataV提供了一套完整的三维模型Web模型开发方案,包括三维模型托管、应用开发、交互开发、应用分发等完整功能。只需69.3元/年,就能体验三维模型Web应用开发功能!
32 8
只需四步,轻松开发三维模型Web应用