【Django】开发日报_8_Day:手机号码管理系统(6)
目录
- 1、实现用户登录
- (0)知识点补充
- (1)搭建页面
- (2)实现身份校验
- (3)中间件处理
- (4)创建中间件样例
- (5)基于中间件实现登录验证
- (6)实现用户注销功能
1、实现用户登录
(0)知识点补充
(1)搭建页面
思路:url->views->html
urls.py
path('login/', account.login),
views->account.py
from django.shortcuts import render
def login(request):
"""登录"""
return render(request,'login.html')
login.html
{% 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>
<div class="form-group">
<label>用户名</label>
<input type="text" class="form-control" id="exampleInputEmail1" placeholder="用户名">
</div>
<div class="form-group">
<label>用户名</label>
<input type="password" class="form-control" placeholder="密码">
</div>
<input type="submit" value="登录" class="btn btn-primary">
</form>
</div>
</body>
</html>
访问效果
(2)实现身份校验
修改一下样式类继承BootStrap.py
from django import forms
class BootStrap:
def __init__(self, *args, **kwargs):
# 引用父类的ini方法
super().__init__(*args, **kwargs)
#循环ModelForm中的字段,给每个字段的插件设置
for name, field in self.fields.items():
#字段中有属性,保留原来属性,没有属性增加属性
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {
"class":"form-control",
"placeholder":field.label
}
class BootStrapModelForm(BootStrap,forms.ModelForm):
pass
class BootStrapForm(BootStrap,forms.Form):
pass
使用form组件form.py
class LoginForm(BootStrapForm):#采用继承
username = forms.CharField(
label="用户名",
widget=forms.TextInput,#(attrs={'class':"form-control",'placeholder':'用户名'})
required=True
)
password = forms.CharField(
label="密码",
widget=forms.PasswordInput(render_value=True),#render_value=True:保留原来字段#(attrs={'class':"form-control",'placeholder':'密码'})
required=True
)
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
# class LoginModelForm(forms.ModelForm):
# class Meta:
# model = models.Admin
# fields = ["username",'password']
视图函数,account.py
from django.shortcuts import render,HttpResponse,redirect
from app01.utils.form import LoginForm
from app01 import models
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': '111', 'password': '111'}
#{'username': '111', 'password': '70a53ebb8836a4400fe2827ab6cc86bf'}
#去数据库进行校验,获取用户对象、None
#admin_object = models.Admin.objects.filter(username=form.cleaned_data['username'],password=form.cleaned_data['password']).first()
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
#用户名为空
if not admin_object:
form.add_error("password","用户名或密码错误")
return render(request, 'login.html', {'form': form})
#用户名和密码正确
#网站随机生成字符串,写到用户浏览器的cookie中,在写入到session中
request.session["info"] = {'id':admin_object.id,'name':admin_object.username}
return redirect("/admin/list/")
return render(request,'login.html',{'form':form})
login.html
{% 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><!--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>
<input type="submit" value="登录" class="btn btn-primary">
</form>
</div>
</body>
</html>
访问页面
(3)中间件处理
给每个页面进行验证(是否已经登录,没登录无法访问网站其他页面)
图解中间件
(4)创建中间件样例
新建目录和文件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render
class M1(MiddlewareMixin):
"""中间件1"""
def process_request(self,request):
#没有返回值,返回None,继续向后走
#有返回值 HttpResponse
print("M1.进来了")
#return HttpResponse("无权访问")
#return render()
#return redirect()
def process_response(self,request,response):
print("M1.走了")
return response
class M2(MiddlewareMixin):
"""中间件2"""
def process_request(self,request):
print("M2.进来了")
def process_response(self,request,response):
print("M2.走了")
return response
修改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.M1',
'app01.middleware.auth.M2',
]
接下来访问页面会发现,每次访问都会调用中间件
符合这个过程
(5)基于中间件实现登录验证
编写中间件
auth.py
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render
class AuthMiddleware(MiddlewareMixin):
"""中间件"""
def process_request(self,request):
#0、排除不需要登录验证就能访问的页面
if request.path_info == "/login/":
return
#1、读取当前访问的用户的session信息,如果能读到,说明已登录过,就可以继续向后走
info_dict = request.session.get("info")
if info_dict:
return
# 2、没登录过,重新登录
return redirect("/login/")
应用中间件
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',
]
访问页面:
没登录就只能看到登录界面
(6)实现用户注销功能
注销:说白了,就是将浏览器cookie中session的数据清除掉。
实现方法
urls,py
path('logout/', account.logout),
account.py
def logout(request):
"""注销"""
request.session.clear()
return redirect("/login/")
修改模板,添加链接和显示昵称
template.py
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title_content %}
{% endblock %}
</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</head>
<body>
<!--导航-->
<div class="bs-example" data-example-id="inverted-navbar">
<nav class="navbar navbar-inverse">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-9" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/pretty/list/">靓号管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-9">
<ul class="nav navbar-nav">
<li><a href="/admin/list/">管理员账户</a></li>
<li><a href="/depart/list/">部门管理</a></li>
<li><a href="/user/list/">用户管理</a></li>
<li><a href="/pretty/list/">靓号管理</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="/login/">登录</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">{{ request.session.info.name }} <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">个人资料</a></li>
<li><a href="#">我的信息</a></li>
<li role="separator" class="divider"></li>
<li><a href="/logout/">注销</a></li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
{% block content %}{% endblock %}
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>
登录网站
实现注销和显示用户昵称功能