目錄
- 1.urls.py
- 2.login/models.py
- 3.views.login和login.html
- 4.views.index
- 4.views.index
- 5.views.logout
- 6.總結(jié)session和forms的搭配
當(dāng)session啟用后,傳遞給視圖request參數(shù)的HttpRequest對(duì)象將包含一個(gè)session屬性,就像一個(gè)字典對(duì)象一樣。你可以在Django的任何地方讀寫request.session屬性,或者多次編輯使用它。
這個(gè)文件在我的C:\Users\17764530215\test\mysite地址
1.urls.py
from django.contrib import admin
from django.urls import path
from login import views
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', views.index),
path('login/', views.login),
path('register/', views.register),
path('logout/', views.logout),
]
策略:
- 未登錄人員,不論是訪問index還是login和logout,全部跳轉(zhuǎn)到login界面
- 已登錄人員,訪問login會(huì)自動(dòng)跳轉(zhuǎn)到index頁面
- 已登錄人員,不允許直接訪問register頁面,需先logout
- 登出后,自動(dòng)跳轉(zhuǎn)到login界面
(wow,這其實(shí)就是我們的功能?。。?/p>
2.login/models.py
from django.db import models
# Create your models here.
class User(models.Model):
gender = (
('male', "男"),
('female', "女"),
)
name = models.CharField(max_length=128, unique=True)
password = models.CharField(max_length=256)
email = models.EmailField(unique=True)
sex = models.CharField(max_length=32, choices=gender, default="男")
c_time = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
class Meta:
ordering = ["-c_time"]
verbose_name = "用戶"
verbose_name_plural = "用戶"
各字段含義:
name: 必填,最長不超過128個(gè)字符,并且唯一,也就是不能有相同姓名; password: 必填,最長不超過256個(gè)字符(實(shí)際可能不需要這么長); email: 使用Django內(nèi)置的郵箱類型,并且唯一; sex: 性別,使用了一個(gè)choice,只能選擇男或者女,默認(rèn)為男; 使用__str__方法幫助人性化顯示對(duì)象信息; 元數(shù)據(jù)里定義用戶按創(chuàng)建時(shí)間的反序排列,也就是最近的最先顯示;
3.views.login和login.html
views.login:
def login(request):
if request.session.get('is_login', None): # 不允許重復(fù)登錄
return redirect('/index/')
if request.method == 'POST':
login_form = forms.UserForm(request.POST) #上一次填寫了這個(gè)表單,所以從這里得到這個(gè)表單的數(shù)據(jù)
message = '請(qǐng)檢查填寫的內(nèi)容!'
if login_form.is_valid():
username = login_form.cleaned_data.get('username')
password = login_form.cleaned_data.get('password')
try:
user = models.User.objects.get(name=username)
except :
message = '用戶不存在!'
return render(request, 'login/login.html', locals())
if user.password == password: #如果用戶名和密碼都成功
# 往session字典內(nèi)寫入用戶狀態(tài)和數(shù)據(jù):
request.session['is_login'] = True #is_login=True表示成功登陸
request.session['user_id'] = user.id
request.session['user_name'] = user.name
return redirect('/index/') #重定向到主頁
else:
message = '密碼不正確!'
return render(request, 'login/login.html', locals())
else:
return render(request, 'login/login.html', locals())
# 不是POST的話,統(tǒng)統(tǒng)轉(zhuǎn)去login.html
login_form = forms.UserForm()
return render(request, 'login/login.html', locals())
我們進(jìn)入login時(shí),會(huì)去session里面找is_login項(xiàng),如果為true就表示已經(jīng)登陸了,所以就重定向到/index/中,進(jìn)入首頁.
如果為False,即沒有登陸,那么往下走。如果是POST方法,那么執(zhí)行一系列操作,如果不是POST,就表示是第一次用GET的方式登陸到這個(gè)login網(wǎng)頁的,那么就用forms.UserForm產(chǎn)生一個(gè)對(duì)象login_form,將其作為參數(shù)傳到login/login.html模板文件中,待會(huì)再介紹這個(gè)文件。
如果為False,且是POST時(shí),就表明是填寫了表單的,這里就涉及很多業(yè)務(wù)邏輯和session的管理了,重點(diǎn)講。如果login_form.is_valid() 如下:通過login_form = forms.UserForm(request.POST)得到填寫的這個(gè)表單數(shù)據(jù),然后去和數(shù)據(jù)庫的用戶名密碼去驗(yàn)證,如果通過了,那么就將request.session['is_login']改為True,表示在登陸狀態(tài),并且把user_id和user_name字段也改成對(duì)應(yīng)的數(shù)據(jù),這個(gè)之后應(yīng)該有用.
下面進(jìn)入login/login.html
!doctype html>
html lang="en">
head>
!-- Required meta tags -->
meta charset="utf-8">
meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
!-- 上述meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
!-- Bootstrap CSS -->
link rel="stylesheet">
title>登錄/title>
/head>
body>
div class="container">
div class="col">
form class="form-login" action="/login/" method="post">
{% if message %}
div class="alert alert-warning">{{ message }}/div>
{% endif %}
{% csrf_token %}
h3 class="text-center">歡迎登錄/h3>
{{ login_form }}
div>
a href="/register/" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" class="text-success " >ins>新用戶注冊(cè)/ins>/a>
button type="submit" class="btn btn-primary float-right">登錄/button>
/div>
/form>
/div>
/div> !-- /container -->
!-- Optional JavaScript -->
!-- jQuery first, then Popper.js, then Bootstrap JS -->
{# 以下三者的引用順序是固定的#}
script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js">/script>
script src="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.js">/script>
script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js">/script>
/body>
/html>
這里重要的地方是這個(gè)語句——{{ login_form }},在這個(gè)位置插入了一個(gè)表單login_form,然后填寫好這個(gè)表單以后,用view里面的login函數(shù)通過執(zhí)行l(wèi)ogin_form = forms.UserForm(request.POST)來獲取填寫的這個(gè)表單數(shù)據(jù),然后去進(jìn)行校驗(yàn)等等操作...
有了這兩個(gè),我們的權(quán)限管理就基本完成了!本質(zhì)上,這倆東西提供了一種機(jī)制————可以對(duì)輸入的用戶數(shù)據(jù)存在session里,然后校驗(yàn)的時(shí)候從session中取出,去判斷是否是合法的用戶。那么,我們只需要再修改一下index.html,也是用session去校驗(yàn),這樣,直接通過網(wǎng)址訪問的用戶,由于沒有session,就會(huì)被攔截!
4.views.index
def index(request):
if not request.session.get('is_login', None): #如果不在登陸狀態(tài),就重定向到login
return redirect('/login/')
return render(request, 'login/index.html') #如果在登陸狀態(tài),就進(jìn)入index.html的模板文件
這里邏輯很清楚:如果不在登陸狀態(tài),就重定向到login;如果在登陸狀態(tài),就直接重定向到真正的login/index.html模板。在這么模板中,我們就可以開發(fā)各種功能了,該demo中的login/index/html如下:
!DOCTYPE html>
!-- Optional JavaScript -->
!-- jQuery first, then Popper.js, then Bootstrap JS -->
{# 以下三者的引用順序是固定的#}
script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js">/script>
script src="https://cdn.bootcss.com/popper.js/1.15.0/umd/popper.js">/script>
script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js">/script>
/body>
/html>
這里重要的地方是這個(gè)語句——{{ login_form }},在這個(gè)位置插入了一個(gè)表單login_form,然后填寫好這個(gè)表單以后,用view里面的login函數(shù)通過執(zhí)行l(wèi)ogin_form = forms.UserForm(request.POST)來獲取填寫的這個(gè)表單數(shù)據(jù),然后去進(jìn)行校驗(yàn)等等操作...有了這兩個(gè),我們的權(quán)限管理就基本完成了!本質(zhì)上,這倆東西提供了一種機(jī)制————可以對(duì)輸入的用戶數(shù)據(jù)存在session里,然后校驗(yàn)的時(shí)候從session中取出,去判斷是否是合法的用戶。那么,我們只需要再修改一下index.html,也是用session去校驗(yàn),這樣,直接通過網(wǎng)址訪問的用戶,由于沒有session,就會(huì)被攔截!
4.views.index
def index(request):
if not request.session.get('is_login', None): #如果不在登陸狀態(tài),就重定向到login
return redirect('/login/')
return render(request, 'login/index.html') #如果在登陸狀態(tài),就進(jìn)入index.html的模板文件
這里邏輯很清楚:如果不在登陸狀態(tài),就重定向到login;如果在登陸狀態(tài),就直接重定向到真正的login/index.html模板。在這么模板中,我們就可以開發(fā)各種功能了,該demo中的login/index/html如下:
html lang="en">
head>
meta charset="UTF-8">
title>首頁/title>
/head>
body>
h1>{{ request.session.user_name }}! 歡迎回來!/h1>
p>
a href="/logout/">登出/a>
/p>
/body>
/html>
最后,再來看看logout的實(shí)現(xiàn)吧
5.views.logout
def logout(request): #登出
if not request.session.get('is_login', None): #如果不在登陸狀態(tài),就直接轉(zhuǎn)發(fā)到登陸界面
# 如果本來就未登錄,也就沒有登出一說
return redirect("/login/")
request.session.flush() #清空session
# 或者使用下面的方法
# del request.session['is_login']
# del request.session['user_id']
# del request.session['user_name']
return redirect("/login/") #重定向到login界面
如果未登陸,那么直接重定向/login/界面,如果是登陸狀態(tài),那么需要先通過 request.session.flush()來清空session,然后再重定向到/login/的登陸界面.
6.總結(jié)session和forms的搭配
forms其實(shí)是在html中,通過將表單和對(duì)象聯(lián)系在一起,就可以很容易在填寫表單后,通過forms去找到填寫的內(nèi)容。
session其實(shí)是權(quán)限校驗(yàn)的利器!沒有session的時(shí)候,用戶可以直接訪問index界面,有session的時(shí)候,index函數(shù)的處理邏輯就變成通過session去判斷是否登陸。當(dāng)然,與之配套,還必須要用login,logout等函數(shù)來維護(hù)好這個(gè)session信息,保證一個(gè)不變性——所有session中的is_login字段為True的時(shí)候,都是真正的登陸用戶.
到此這篇關(guān)于Django中session進(jìn)行權(quán)限管理的使用的文章就介紹到這了,更多相關(guān)Django session權(quán)限管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
您可能感興趣的文章:- Django 權(quán)限管理(permissions)與用戶組(group)詳解
- django自帶的權(quán)限管理Permission用法說明
- Django 自定義權(quán)限管理系統(tǒng)詳解(通過中間件認(rèn)證)
- django認(rèn)證系統(tǒng)實(shí)現(xiàn)自定義權(quán)限管理的方法
- Django RBAC權(quán)限管理設(shè)計(jì)過程詳解
- Django-Rest-Framework 權(quán)限管理源碼淺析(小結(jié))
- django認(rèn)證系統(tǒng)實(shí)現(xiàn)自定義權(quán)限管理的方法