Python实现员工管理系统(Django页面版 ) 七

news2025/1/22 12:53:21

        各位小伙伴们好久不见,2024年即将到来,小编在这里提前祝大家新的一年快快乐乐,能够事业有成,学习顺心,家庭和睦,事事顺利。

        今天我们本篇要实现的是一个登录界面的实现,其实登录界面的实现看着挺好实现的,其实里面需要注意到的点还是很多的,因此我可能会需要多篇博客进行一个讲解,接下来我们开始本次的登录界面的实现。

         大家可以从上面的登录界面可以发现,我们本次需要完成的是用户在输入账号和密码后,然后再输入一个验证码后点击登录就能进入到我们的界面中,在这里我们用户输入的账号和密码是与我们上一篇博客是挂钩的,如果有不明白的朋友可以去看一下。

Python实现员工管理系统(Django页面版 ) 六-CSDN博客

        其次我们对于不同的等级的用户进去是需要展示不同的页面的,就比如员工他就只能看看他的同事是哪些,还有他的任务是什么,他也不能进行添加,删除,修改操作,其实这个板块是属于用户权限的划分,我们在本章博客先不做这个,我们把这个伏笔埋一下。        

        好好好,也不多说这么多啦,咱先把基础的模板搞定,到哪步咱再说哪步。

        在之前我们都是使用model.ModelFrom来对数据库中的数据进行一个修饰,一般来讲我们在对数据进行操作的时候我们用这个是比较方便的,那对于我们并不需要对数据库的数据进行操作的时候我们有没有更简单的方式来解决呢,下面我们来介绍一下model.Form。

model.form是Django中的一个模块,用于创建和处理表单。它是一个基于Model的表单,可以很方便地与数据库模型进行交互。

        下面我们在我们的views文件夹下,新建一个login.py

        我们可以从最上面的展示效果来看,我们需要三个字段,分别是用户名,密码和验证码,因此我们需要新建一个Form类来创建这三个字段。

login.py

from django import forms
from project_manage.utils.encryption import md5

class LoginForm(forms.Form):
    username = forms.CharField(label='用户',widget=forms.TextInput(attrs={'class':'from-control','autocomplete':'off'}))
    password = forms.CharField(label='用户',widget=forms.PasswordInput(attrs={'class':'from-control','autocomplete':'off'}))
    code = forms.CharField(label='验证码',widget=forms.TextInput(attrs={'class':'from-control','autocomplete':'off'}))

    def clean_password(self):
        pwd = self.cleaned_data.get('password')
        return md5(pwd)

          其中的md5是我们在上一篇博客中对密码的一个加密函数,不了解的朋友可以去看一下。我们会发现其实Form和ModelForm的使用方式是差不多的,只是Form我们用的更加简单。那个钩子方法会将我们输入的密码进行一个md5加密并返回给数据库。

        下面我们来编写我们的模块函数,由于这次的登录界面对比之前的那些模板方法可能比较难理解,我就分开写方便大家理解。

首先我们在访问登录界面是一个get请求访问,那他就会给我们返回一个登录界面的展示

login.py

def login(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request,'login.html',{'form':form})

在模板文件中创建一个login.html文件

login,html

{% load static %}
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录页</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
    <style>
        .account {
            width: 450px;
            border: 2px solid #2196f300;
            background-color: #fff8d240;
            margin-left: auto;
            margin-right: auto;
            border-radius: 5%;
            padding: 20px;
            margin-top: 50px;
            box-shadow: 7px 11px 5px #9e9e9e;
        }
    </style>
</head>
<body">
<div class="account">
    <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">
            <div class="row">
                <div class="col-xs-7">
                    <label>验证码</label>
                    {{ form.code }}
                    <span style="color: red">{{ form.code.errors.0 }}</span>
                </div>
                <div class="col-xs-5">
                    <button style="border: none">
                        <img src="/image/code/">
                    </button>
                </div>
            </div>

        </div>

        <button type="submit" class="btn btn-success">登录</button>
    </form>
</div>

</body>
</html>

          下面我们先对验证码进行一个处理,验证码其实就是往我们的页面插入一张图片,然后让用户进行输入图片中的信息即可,如果输入错误提示验证码错误。

在utils文件夹下创建一个code.py用于存放验证码

code.py

# -*- coding:utf-8 -*-
from PIL import Image,ImageDraw,ImageFont
from random import randint,choice

def create_captcha_content():
    # 创建一张图片,模式为RGB模式  全白
    img = Image.new(mode='RGB',size=(110,40),color=(255,255,255))
    # 创建一个画笔
    draw = ImageDraw.Draw(img,mode='RGB')
    # 设置字体
    font = ImageFont.truetype(r'C:\Windows\Fonts\simhei.ttf',size=30)
    # 选择图片内容
    text = 'ABCDEFG123456789'
    captcha_text = ''
    for i in range(4):
        captcha_text += choice(text)
    x = 15
    for i in captcha_text:
        R = randint(0,255)
        G = randint(0,255)
        B = randint(0,255)

        draw.text((x, 3),
                  text=i,
                  font=font,
                  fill=f"rgb({R},{G},{B})"
                  )
        # 调整下一个字的间隔
        x += 20

    # 在图像中展示线段作为干扰用户输入数据的方式
    for i in range(1, randint(3,6)):
        x1, y1 = randint(0,100),randint(0,30)
        x2, y2 = randint(0,100),randint(0,30)
        R = str(randint(0,255))
        G = str(randint(0,255))
        B = str(randint(0,255))
        draw.line((x1,y1,x2,y2),fill=f'rgb({R},{G},{B})',width=2)

    # 在图像中展示散点作为干扰用户输入数据的方式
    for i in range(1,randint(100,150)):
        x1,y1 = randint(0,100),randint(0,30)
        R = str(randint(0,255))
        G = str(randint(0,255))
        B = str(randint(0,255))
        draw.point((x1,y1),fill=f'rgb({R},{G},{B})')

    # 返回图像和验证码
    return [img,captcha_text]

        在这里就不对里面的代码进行解释了,不过需要注意的是对于字体的选择我是使用电脑自带的字体,下面我开介绍一下如何使用电脑自带的字体。

进入C盘 ----》 打开Windows文件   找到Fonts文件夹

然后进去后随便找一个觉得合适的字体,然后右击选择属性,找到文件的路径即可

 

好的,现在回到我们的模块函数

        我们需要将把验证码通过图像的形式插入到我们的界面中去,因此我们需要封装我们的验证码模块函数,我们在进行页面刷新的时候验证码也能跟着刷新

login.py

from io import BytesIO
def image_code(request):
    image,text = create_captcha_content()
    # 将验证码的值放入到session中
    request.session['image_code'] = text
    # 60s的时效性
    request.session.set_expiry(60)
    stream = BytesIO()
    image.save(stream,'png')
    return HttpResponse(stream.getvalue())

        其中的session是我们用户和服务器之间的一个会话,我们可以将用户的一些信息放入到这个session中,方便我们服务器进行后续的判断查找。然后我们会在里面设置一个时效性,类似与cookie,在这段时间后服务器就会将该用户信息删除,如果服务器检查到存在该用户的信息的话,那么用户下次进入时就不用进行登录。

配置验证码路由  

urls.py

    # 验证码
    path('image/code/',login.image_code),

        我们在进行用户登录的时候,首先是需要验证我们输入的验证码是否与图像展示的验证码一样,然后再到数据库中校验是否存在这个用户,存在即返回界面,不存在就给出错误信息。

login.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 user_input_code.upper() != code.upper():
            form.add_error('code','验证码错误')
            return render(request,'login.html',{'form':form})

        # 账号密码验证,数据库校验
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            # print(form.cleaned_data)
            form.add_error('password','用户名或者密码错误')
            return render(request,'login.html',{'form':form})
        # 生成字符串存储到cookie和session当中去
        info = {
            'id':admin_object.id,
            'name':admin_object.username,
            'role':admin_object.role
        }
        request.session['info'] = info

        # 时效性           ------ 一个点
        request.session.set_expiry(60 * 60 * 24)

        # request.session.set_expiry(10)

        return redirect('/')
    return render(request,'login.html',{'form':form})

  用户退出模块函数

def logout(request):
    request.session.clear()
    return redirect('/login/')

        其实用户退出很简单,只需要把用户当前的session清空即可,然后返回到登录界面

配置路由

urls

    # 登录页面
    path('login/',login.login),

    # 退出登录
    path('logout/',login.logout),

        其实做到这里差不多登录界面就完成了,但是里面还没有做到用户权限的划分,我们在后面的博客进行讲解吧。最后,还是祝大家新的一年快乐!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1344302.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

php学习06-魔术常量

有九个魔术常量它们的值随着它们在代码中的位置改变而改变。例如 LINE 的值就依赖于它在脚本中所处的行来决定。这些特殊的常量不区分大小写&#xff0c;如下&#xff1a; 参考

SpringBoot知识

1、Spring和SpringBoot对比 2、版本调整 &#xff08;1&#xff09;先排除是否是JDK与SpringBoot的版本不一致导致的&#xff1a;如JDK1.8和SpringBoot3.1.5冲突&#xff1b; &#xff08;2&#xff09;调整编译版本 &#xff08;3&#xff09;调整maven的jdk &#xff08;4&…

AI又进化了,AI 写代码工具

今年 AI 的发展可谓一日千里&#xff0c;相信不少同学应该都用过 AI 来帮助自己提高开发效率吧&#xff1f; 比如让 AI 根据注释生成代码、解释整段代码、提供技术问题的答疑、修改 Bug、生成单元测试等等。 在 12 月 28 日刚刚结束的 WAVE SUMMIT 深度学习开发者大会上&…

引领手游技术潮流:武汉灰京文化的卓越技术创新与市场推广支持

在数字娱乐领域&#xff0c;手游行业正蓬勃发展&#xff0c;为数以亿计的玩家提供了丰富的娱乐选择。武汉灰京文化&#xff0c;作为该领域的佼佼者&#xff0c;以其强大的技术创新和全面的市场推广支持&#xff0c;为合作伙伴的成功铺平了道路&#xff0c;不仅提升了游戏质量&a…

Amlogic HDMI驱动分析

目录 一、简介 二、代码结构介绍 三、HDMI资料 四、宏观认识一下HDMI 1、硬件连接 2、Amlogic方案中HDMI的位置 3、Amlogic HDMI驱动模块的划分 五、HDMI-RX驱动分析 1、芯片手册解读 2、RX -makefile 3、驱动模型分析 4、RX的运行 5、HDMI RX调试 六、HDMI-TX驱…

单列集合Collection常用api

集合体系结构 Collection Collection是单列集合的祖宗接口&#xff0c;它的功能是全部单列集合都可以继承使用的。 public static void main(String[] args) {//TODO Collection类 所有集合的接口 /*public boolean add(E e) 添加public void clear() …

Ubuntu20.04 上启用 VCAN 用作本地调试

目录 一、启用本机的 VCAN​ 编辑 1.1 加载本机的 vcan 1.2 添加本机的 vcan0 1.3 查看添加的 vcan0 1.4 开启本机的 vcan0 1.5 关闭本机的 vcan0 1.6 删除本机的 vcan0 二、测试本机的 VCAN 2.1 CAN 发送数据 代码 2.2 CAN 接收数据 代码 2.3 CMakeLists.…

图像质量评估:使用 SSIM 计算图像相似性

在图像处理领域&#xff0c;衡量两幅图像之间相似性的一种常见方法是使用结构相似性指数&#xff08;SSIM&#xff09;。SSIM 是一种全参考的图像质量评估指标&#xff0c;它不仅考虑了图像的亮度、对比度&#xff0c;还考虑了结构信息。在本文中&#xff0c;我们将介绍一个使用…

Qt QAction添加图片

QAction用的时候&#xff0c;时常需要添加图片&#xff0c;如上图所示&#xff0c;代码如下所示&#xff1a; 测试的图片格式包含png,jpg,bmp,svg&#xff0c;其他未测试

OpenCV-Python(9):图像基础操作

目录 学习目标 获取图像像素并修改像素值 获取图像属性 图像ROI 拆分及合并图像通道 图像边缘扩充 学习目标 获取像素值并修改获取图像的属性(信息)图像的ROI获取图像通道拆分及合并图像扩边 获取图像像素并修改像素值 几乎所有这些操作与Numpy 的关系要比与OpenCV 的…

大语言模型(LLM)框架及微调 (Fine Tuning)

大语言模型&#xff08;LLM&#xff09; 技术作为人工智能领域的一项重要创 新在今年引起了广泛的关注。 LLM 是利用深度学习和大数据训练的人工智能系统&#xff0c;专门 设计来理解、生成和回应自然语言。这些模型通过分析大量 的文本数据来学习语言的结构和用法&#xff0c;…

跟着LearnOpenGL学习11--材质

文章目录 一、材质二、设置材质三、光的属性四、不同的光源颜色 一、材质 在现实世界里&#xff0c;每个物体会对光产生不同的反应。 比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的光。 有些物体反…

器件的静态特性

器件的静态特性 静态特性&#xff08;伏安特性&#xff09; 1.器件在导通或关断的状态下&#xff0c;其电压与电流对应关系。 2.静态过程体现器件最基本的电压与电流稳态特性。 动态特性&#xff08;开关特性&#xff09; 1.器件在开或关过程中&#xff0c;其电压、电流随时…

关于java循环结构for

关于java循环结构for 在上一篇文章中&#xff0c;我们了解到了while和do…while的结构以及用法&#xff0c;这篇文章我们主要学习一下最常用的循环结构&#xff0c;for结构&#x1f600;&#xff0c;这个结构理解起来相对while结构会难一些&#xff0c;本篇文章内容会很多&…

深入Mybatis数据源

数据源是持久层框架中最核心的组件之一&#xff0c;在实际工作中比较常见的数据源有 C3P0、Apache Common DBCP、Proxool 等。作为一款成熟的持久化框架&#xff0c;MyBatis 不仅自己提供了一套数据源实现&#xff0c;而且还能够方便地集成第三方数据源。 javax.sql.DataSourc…

Linux之缓冲区的理解

目录 一、问题引入 二、缓冲区 1、什么是缓冲区 2、刷新策略 3、缓冲区由谁提供 4、重看问题 三、缓冲区的简单实现 一、问题引入 我们先来看看下面的代码&#xff1a;我们使用了C语言接口和系统调用接口来进行文件操作。在代码的最后&#xff0c;我们还使用fork函数创建…

单纯形的几何意义 Simplex

单纯形是 n 维空间 n1 个仿射无关的点的集合的凸包。在几何意义上&#xff1a; 1维单纯形是一个线段2维单纯形是一个三角形3维单纯形是一个四面体&#xff08;tetrahedron&#xff09;

MySQL线上慢SQL问题分析处理小记

相同数据量表结构&#xff0c;线上执行12s 本地执行0.1s过程分析 1. 慢SQL信息 SELECT t1.id,t2.idFROM t_platform_target_standard_target_index t1LEFT JOIN t_platform_target_standard t2 ON t1.target_number t2.target_numberWHERE t1.delete_flag 0 AND t2.user_num …

Linux上管理不同版本的 JDK

当在 Linux 上管理不同版本的 JDK 时&#xff0c;使用 yum 和 dnf 可以方便地安装和切换不同的 JDK 版本。本文将介绍如何通过这两个包管理工具安装 JDK 1.8 和 JDK 11&#xff0c;并利用软连接动态关联这些版本。 安装 JDK 1.8 和 JDK 11 使用 yum 安装 JDK 1.8 打开终端并…

如何在 Linux 中配置 firewalld 规则

什么是FirewallD “firewalld”是firewall daemon。它提供了一个动态管理的防火墙&#xff0c;带有一个非常强大的过滤系统&#xff0c;称为 Netfilter&#xff0c;由 Linux 内核提供。 FirewallD 使用zones和services的概念&#xff0c;而 iptables 使用chain和rules。与 ip…