
上篇文章中講到 Django 如何啟動以及配置 sessions 功能。sessions 功能用是跟蹤用戶的狀態(tài),經(jīng)常結(jié)合 Cookie 功能實現(xiàn)自動登錄功能。 所謂的“自動登錄”指的是:我們登錄一些網(wǎng)站,在不關(guān)閉瀏覽器以及距離上次登錄時間不是很長的情況下。無論我們在新的標簽頁打開網(wǎng)站,還是關(guān)閉頁面重新打開網(wǎng)站,登錄狀態(tài)一直保持著。本文內(nèi)容有兩個:一是利用 Django 實現(xiàn)自動登錄功能,二是揭開“自動登錄”的神秘面紗。
1 新建項目
我為了將本系列所有文章的示例代碼保持集中狀態(tài),所以直接在 Django_demo 項目中創(chuàng)建應(yīng)用。如果第一次看這文章,需要先創(chuàng)建項目(project),再創(chuàng)建應(yīng)用(app)。我新建的應(yīng)用是 demo_session。

然后在 setting.py 中啟動請用,并檢查 sessions 組件是否啟動。

因為需要 Cookie 功能,所以同樣需要在 settings.py 增加一些配置。
SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key
SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認)
SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認)
SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie
SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認)
SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認)
SESSION_SAVE_EVERY_REQUEST = False # 是否設(shè)置關(guān)閉瀏覽器使得Session過期
SESSION_COOKIE_AT_BROWSER_CLOSE = False # 是否每次請求都保存Session,默認修改之后才能保存
如果你將 SESSION_SAVE_EVERY_REQUEST 設(shè)置為 True, 那么關(guān)閉瀏覽器之后,需要重新登錄。
2 流程
應(yīng)用中會涉及到 3 個頁面,所以我繪制流程圖幫助理解。

3 實現(xiàn)
3.1 新建 model
服務(wù)器接收到瀏覽器傳送過來登錄信息,需要驗證賬號和密碼等信息。所以需要新建 model 保存信息,以便后續(xù)跟數(shù)據(jù)庫做校驗。這里我只是簡單保存信息,登錄驗證后續(xù)講解。
class User(models.Model):
username = models.CharField(max_length=20) # 賬號
password = models.CharField(max_length=20) # 密碼
nickname = models.CharField(max_length=20) # 昵稱
3.2 新建 form
用戶將登錄信息發(fā)送給服務(wù)器是用到 POST 請求,所以需要創(chuàng)建表單。在應(yīng)用目錄下新建名為 forms 目錄,然后創(chuàng)建 forms.py 文件。
from django.forms import ModelForm, TextInput, PasswordInput
from demo_session.models import User
class UserForm(ModelForm):
class Meta:
model = User
fields = ['username', 'password', ] # 只顯示 model 中指定的字段
# 指定呈現(xiàn)樣式字段、指定 CSS 樣式
widgets = {
'username': TextInput(attrs={'class': 'text',
'value': 'monkey'}),
'password': PasswordInput(attrs={'value': '13245678', })
}
3.3 新建視圖
頁面一共有三個,分別是登錄、首頁、登出。具體實現(xiàn)如下:
# view.py
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from demo_session.form.forms import UserForm
# 用戶登錄
def login_view(request):
# 過濾 POST 方法的請求
if request.method == 'POST':
userfrom = UserForm(request.POST)
# 驗證表單
if userfrom.is_valid():
username = userfrom.cleaned_data['username']
password = userfrom.cleaned_data['password']
# ... 執(zhí)行驗證登錄信息操作
# 將等你信息傳遞給 Session 對象, 實際應(yīng)用中不建議這么操作
request.session['username'] = username
# 跳轉(zhuǎn)到頁面
return HttpResponseRedirect('/index/')
else:
# 不是 GET 請求則顯示表單
userfrom = UserForm()
template_view = 'login.html'
return render(request, template_view, {'userfrom': userfrom})
# 成功登錄之后, 跳轉(zhuǎn)首頁
def index_view(request):
username = request.session.get('username', '')
# print(username)
template_view = 'index.html'
return render(request, template_view, {'username': username})
# 登出操作
def logout_view(request):
# 刪除 session
del request.session['username']
return HttpResponse('登出成功')
3.4 對應(yīng)模板
視圖 login_view, index_view 對應(yīng)的模板是 login.html, index.html。
其中 login.html 的實現(xiàn)如下:
{% load staticfiles %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
<meta charset="UTF-8">
<title>登錄</title>
<link href="{% static 'css/style.css' %}" rel="stylesheet" type='text/css' >
<!--webfonts-->
<link href="{% static 'css/font.css' %}" rel='stylesheet' type='text/css'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="application/x-javascript">
addEventListener("load", function() { setTimeout(hideURLbar, 0); }, false);
function hideURLbar(){ window.scrollTo(0,1); }</script>
</head>
<body>
<div class="main">
<div class="login-form">
<h1>Member Login</h1>
<div class="head">
<img src="{% static 'images/user.png' %}" alt=""/>
</div>
<form action="" method="POST">
{% csrf_token %}
{{ userfrom.username }}
{{ userfrom.password }}
<div class="submit"><input type="submit" value="login" ></div>
<p><a href="#">Forgot Password ?</a></p>
</form>
</div>
</div>
</body>
</html>
index.html 的實現(xiàn)如下:
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
<div >
<h3>歡迎 {{username}} 到來~</h3>
<div class="submit"><a href="/logout"><input type="submit" value="退出登錄" ></a></div>
</div>
</body>
</html>
3.5 配置路由
最后一步,在 urls.py 中配置訪問路徑:
from demo_session.views import login_view, index_view, logout_view
urlpatterns = [
# demo_session
path('login/', login_view, name='login'),
path('index/', index_view, name='index'),
path('logout/', logout_view, name='index'),
]
4 實現(xiàn)效果
用戶訪問 http://127.0.0.1/login 進行登錄操作。

當點擊 login 成功之后,會跳轉(zhuǎn)到首頁,首頁會顯示用戶名。同時,Cookie 中多了一個 sessionid 的字段。這字段名就是我們在 setttings.py 定義的。

查詢數(shù)據(jù)庫 django_session 表的內(nèi)容,會多出一條數(shù)據(jù)。

表中的字段含義如下:
- session_key: 就是服務(wù)器給用戶返回的id。在瀏覽器當中,這個值是保存為sessionid
- session_data: 這是一個加密后的信息,用來保存用戶名和密碼等信息
- expire_data: 過期時間,Django可以設(shè)置過期時間
在新的標簽頁中打開首頁,依然能看到 username 信息。這證明能自動登錄。

如果用戶退出登錄,再訪問首頁。這時會發(fā)現(xiàn)看不到了 username 信息了。

5 小結(jié)
實現(xiàn)自動登錄功能其實不難,只需要在 Django 的 Sessions 組件。然后根據(jù)場景需要,在 settings.py 配置 session 以及 cookie 等信息。
往前 Django 學習筆記文章
Django 學習筆記之環(huán)境搭建
Django 學習筆記之初始
Django 學習筆記之視圖與URL配置
Django 學習筆記之模板
Django 學習筆記之模型(上)
Django 學習筆記之模型(下)
Django 學習筆記之后臺管理
Django 學習筆記之模型表單
Django 學習筆記之使用舊數(shù)據(jù)庫
Django 實戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(上)
Django 實戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(下)
Django 學習筆記之模型高級用法(上)
Django 學習筆記之模型高級用法(下)
Django 實現(xiàn)分頁功能
Django 使用會話( sessions )功能
本文原創(chuàng)發(fā)布于微信公眾號「極客猴」,歡迎關(guān)注第一時間獲取更多原創(chuàng)分享