from django.db import models
class Admin(models.Model):
""" 管理员 """
username = models.CharField(verbose_name="用户名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=64)
def __str__(self):
return self.username
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>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/" style="width: 125px;">
</div>
</div>
</div>
<input type="submit" value="登 录" class="btn btn-primary">
</form>
</div>
</body>
</html>
- 1.3:如果用户名、密码正确,登录成功,写入cookie到浏览器,session到后台
from django.shortcuts import render, redirect,HttpResponse
from app01 import models
from app01.utils.bootstrap import BootStrapForm
from django import forms
from io import BytesIO
from app01.utils.encrypt import md5
from app01.utils.code import check_code
class LoginForm(BootStrapForm):
username = forms.CharField(
label="用户名",
widget=forms.TextInput,
required=True
)
password = forms.CharField(
label="密码",
widget=forms.PasswordInput(render_value=True), # 错误提示的时候,内容不清空
required=True # 必填,默认为True
)
code = forms.CharField(
label="验证码",
widget=forms.TextInput,
required=True
)
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
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():
# print(form.cleaned_data) # {'username': 'xwl', 'password': '1cd19cf980df7815e8303ab92ff66296'}
# print(form.cleaned_data) # {'username': 'xwl', 'password': '1cd19cf980df7815e8303ab92ff66296',"code":xxx}
# 去数据库校验用户名和密码是否正确,获取用户对象、None
# admin_object = models.Admin.objects.filter(username=xxx, password=xxx).first()
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
if not admin_object:
form.add_error("password", "用户名或密码错误") # 主动在username字段显示错误信息
# form.add_error("username", "用户名或密码错误")
return render(request, 'login.html', {'form': form})
# 用户名和密码正确
# 网站生成随机字符串,写入浏览器的cookie中,再写入到session中
request.session["info"] = {'id': admin_object.id, 'name': admin_object.username}
# sesion可以保存7天
request.session.set_expiry(60 * 60 * 24 * 7)
return redirect('/admin/list/')
return render(request,"login.html",{"form":form})
- 2.网站的某些界面,必须要登录才能访问,未登录跳转到登录界面,我们可以在每个视图函数中判断,但是这个太麻烦了。Django为我们提供了一个轻量级的组件,中间件实现起来就很方便了。
- 2.1:中间件介绍
- 2.1.1:什么是中间件?
- 是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局,所以需要谨慎实用,用不好会影响到性能
- 2.1.2:中间件可以定义五个方法,分别是:(主要的是process_request和process_response),在自己定义中间件时,必须继承MiddlewareMixin
process_request(self,request)
process_view(self, request, callback, callback_args, callback_kwargs)
process_template_response(self,request,response)
process_exception(self, request, exception)
process_response(self, request, response)
- 2.1.3:中间件流程
如果方法中没有返回值(返回None),继续向后走
如果有返回值 HttpResponse、render 、redirect,则不再继续向后执行。
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,redirect,HttpResponse
class AuthMiddleWare(MiddlewareMixin):
def process_request(self,request):
# 排除不需要登录运行访问的界面
if request.path_info in ['/login/','/image/code/']:
return
# 1.读取当前访问的用户的session信息,如果能读到,说明已登陆过,就可以继续向后走
info_dict = request.session.get("info")
# 如果登录过,继续往后走
if info_dict:
return
# 没登录过,返回登录界面
return redirect('/login/')
- 2.2.2:配置中间件,setting.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',
'app01.middleware.auth.AuthMiddleWare',
]
- 3.如上所示,我们就实现了登录功能及登录验证