1、創(chuàng)建數(shù)據(jù)庫(kù)的管理員表
在models.py 中定義admin表,為了簡(jiǎn)單,表里只有用戶名和密碼還有默認(rèn)加的id 三個(gè)字段
from django.db import models
# Create your models here.
class Admin(models.Model):
username = models.CharField(verbose_name="用戶名",max_length=16)
passwd = models.CharField(verbose_name="密碼",max_length=64)
執(zhí)行創(chuàng)建表的語(yǔ)句
py -3 manage.py makemigrations
py -3 manage.py migrate
然后自己手動(dòng)插入一些用戶
2、登錄界面和登錄視圖
在urls.py中加入路徑
from django.urls import path
from app01.views import user,depart,pretty,admin,account
urlpatterns = [
#path('admin/', admin.site.urls),
path('depart/list/', depart.depart_list),
path('depart/add/', depart.depart_add),
path('depart/delete/', depart.depart_delete),
#http://127.0.0.1:8000/depart/2/edit/
path('depart/<int:nid>/edit/', depart.depart_edit),
path('user/list/', user.user_list),
path('user/add/', user.user_add),
path('user/<int:nid>/edit/', user.user_edit),
path('user/<int:nid>/delete/', user.user_delete),
path('pretty/list/', pretty.pretty_list),
path('pretty/add/', pretty.pretty_add),
path('pretty/<int:nid>/edit/', pretty.pretty_edit),
path('pretty/<int:nid>/delete/', pretty.pretty_delete),
path('admin/add/', admin.admin_add),
path('admin/list/', admin.admin_list),
path('admin/<int:nid>/edit/',admin.admin_edit),
path('login/account/',account.login), #這個(gè)是登錄的
]
在寫登錄的視圖函數(shù)account.py
我把不同模塊的視圖函數(shù)拆分了,不同功能模塊的一個(gè)py文件,在app01目錄下創(chuàng)建目錄views, 在views目錄下分類寫視圖函數(shù),主要要把原始的views.py文件刪除
登錄使用的Form組件
獲取到用戶輸入的數(shù)據(jù)后要對(duì)數(shù)據(jù)進(jìn)行校驗(yàn),根數(shù)據(jù)庫(kù)里面的值
再有如果驗(yàn)證通過(guò)要request.session 通過(guò)這個(gè)生成session, django會(huì)自動(dòng)處理,生成一個(gè)session保存到數(shù)據(jù)庫(kù),并把這個(gè)session返回給瀏覽器。
from django.shortcuts import render,redirect
from django import forms
from app01.utils.encrypt import md5
from app01 import models
class LoginForm(forms.Form):
username = forms.CharField(
label="用戶名",
widget=forms.TextInput,
required=True,
)
passwd = forms.CharField(
label="密碼",
widget=forms.PasswordInput(render_value=True),
required=True
)
# 這個(gè)init方式是給自己加樣式的
def __init__(self, *args,**kwargs):
super().__init__(*args,**kwargs)
for name ,field in self.fields.items():
#字段中有屬性,保留原來(lái)的屬性,沒有屬性,才增加
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
field.widget.attrs = {"class":"form-control"}
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) #獲取到的值是一個(gè)字典{'username': 'root', 'passwd': '1234'}
#校驗(yàn)數(shù)據(jù)庫(kù)的用戶名和密碼
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
if not admin_object:
form.add_error('passwd','用戶名或密碼錯(cuò)誤')
return render(request,'login.html',{'form':form})
#用戶名和密碼正確
#網(wǎng)站生成隨機(jī)字符串; 寫到用戶瀏覽器的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 的內(nèi)容
{% 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-radius: 5px;
border: 1px solid #dddddd;
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 %}
{% for field in form %}
<div class="form-group">
<label >{{ field.label }}</label>
{{ field }}
<span style="color:red">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary">提交</button>
</form>
</div>
<script src="{% static 'js/jquery-3.7.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>
3、中間件實(shí)現(xiàn)登錄鑒權(quán)
在開始我們寫了一個(gè)功能后,把django項(xiàng)目運(yùn)行起來(lái),直接方法url就能訪問(wèn)到了,正常來(lái)說(shuō)是只有登錄后的用戶才能訪問(wèn)到,django中給我們提供了中間件,可以通過(guò)中間件來(lái)實(shí)現(xiàn)鑒權(quán)
在django 中可以定義多個(gè)中間件,中間件就是一個(gè)類,類里面定義有兩個(gè)函數(shù)一個(gè)是process_request進(jìn)入的,穿過(guò)所有的中間件到達(dá)視圖函數(shù),視圖函數(shù)返回結(jié)果通過(guò)process_response函數(shù)返回給瀏覽器文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-638991.html
- 定義中間件
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect
class AuthMiddleWare(MiddlewareMixin):
"""中間件判斷是否登錄"""
def process_request(self,request):
# 1、排除那些不需要登錄就能訪問(wèn)的頁(yè)面
# request.path_info 獲取當(dāng)前用戶請(qǐng)求的URL ru /login/account/
if request.path_info == '/login/account/':
return
# 2、讀取當(dāng)前訪問(wèn)的用戶的session信息,如果能讀到,說(shuō)明以登錄過(guò),就可以繼續(xù)向后走
info_dict = request.session.get("info")
if info_dict:
return
# 3、沒有登錄過(guò),重新回到登錄頁(yè)面
return redirect('/login/account/')
- 使用中間件,在settings.py中注冊(cè)中間件
會(huì)按這個(gè)順序執(zhí)行,中間件定義好后,會(huì)自動(dòng)調(diào)傭
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',
]
中間件添加好后,你再?zèng)]有登錄的情況下去訪問(wèn)http://127.0.0.1:8000/user/list/ 這些頁(yè)面會(huì)自動(dòng)跳轉(zhuǎn)到登錄界面。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-638991.html
到了這里,關(guān)于django實(shí)現(xiàn)登錄和登錄的鑒權(quán)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!