各位小伙伴们好久不见,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 %}
登录页
下面我们先对验证码进行一个处理,验证码其实就是往我们的页面插入一张图片,然后让用户进行输入图片中的信息即可,如果输入错误提示验证码错误。
在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),
其实做到这里差不多登录界面就完成了,但是里面还没有做到用户权限的划分,我们在后面的博客进行讲解吧。最后,还是祝大家新的一年快乐!!!