




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
Django3Web應(yīng)用開發(fā)實戰(zhàn)(下篇)目錄\h第10章Auth認證系統(tǒng)\h10.1內(nèi)置User實現(xiàn)用戶管理\h10.2發(fā)送郵件實現(xiàn)密碼找回\h10.3模型User的擴展與使用\h10.4權(quán)限的設(shè)置與使用\h10.5自定義用戶權(quán)限\h10.6設(shè)置網(wǎng)頁的訪問權(quán)限\h10.7用戶組的設(shè)置與使用\h第11章常用的Web應(yīng)用程序\h11.1會話控制\h11.1.1會話的配置與操作\h11.1.2使用會話實現(xiàn)商品搶購\h11.2緩存機制\h11.2.1緩存的類型與配置\h11.2.2緩存的使用\h11.3CSRF防護\h11.4消息框架\h11.4.1源碼分析消息框架\h11.4.2消息框架的使用\h11.5分頁功能\h11.5.1源碼分析分頁功能\h11.5.2分頁功能的使用\h11.6國際化和本地化\h11.6.1環(huán)境搭建與配置\h11.6.2設(shè)置國際化\h11.6.3設(shè)置本地化\h11.7單元測試\h11.7.1定義測試類\h11.7.2運行測試用例\h11.8自定義中間件\h11.8.1中間件的定義過程\h11.8.2中間件實現(xiàn)Cookie反爬蟲\h11.9異步編程\h11.9.1使用多線程\h11.9.2啟用ASGI服務(wù)\h11.9.3異步視圖\h11.9.4異步與同步的轉(zhuǎn)換\h11.10信號機制\h11.10.1內(nèi)置信號\h11.10.2自定義信號\h11.10.3訂單創(chuàng)建與取消\h第12章第三方功能應(yīng)用\h12.1DjangoRestFramework框架\h12.1.1DRF的安裝與配置\h12.1.2序列化類Serializer\h12.1.3模型序列化類ModelSerializer\h12.1.4序列化的嵌套使用\h12.2驗證碼生成與使用\h12.2.1DjangoSimpleCaptcha的安裝與配置\h12.2.2使用驗證碼實現(xiàn)用戶登錄\h12.3站內(nèi)搜索引擎\h12.3.1DjangoHaystack的安裝與配置\h12.3.2使用搜索引擎實現(xiàn)產(chǎn)品搜索\h12.4第三方網(wǎng)站實現(xiàn)用戶注冊\h12.4.1Social-Auth-App-Django的安裝與配置\h12.4.2微博賬號實現(xiàn)用戶注冊\h12.5異步任務(wù)和定時任務(wù)\h12.5.1Celery的安裝與配置\h12.5.2異步任務(wù)\h12.5.3定時任務(wù)\h12.6即時通信——在線聊天\h12.6.1Channels的安裝與配置\h12.6.2Web在線聊天功能\h第13章信息反饋平臺的設(shè)計與實現(xiàn)\h13.1項目設(shè)計與配置\h13.1.1項目架構(gòu)設(shè)計\h13.1.2MySQL搭建與配置\h13.1.3功能配置\h13.1.4數(shù)據(jù)庫架構(gòu)設(shè)計\h13.2程序功能開發(fā)\h13.2.1路由與視圖函數(shù)\h13.2.2使用Jinja2編寫模板文件\h13.2.3Admin后臺系統(tǒng)\h13.3測試與運行\(zhòng)h13.3.1編寫單元測試\h13.3.2運行與上線\h第14章個人博客系統(tǒng)的設(shè)計與實現(xiàn)\h14.1項目設(shè)計與配置\h14.1.1項目架構(gòu)設(shè)計\h14.1.2功能配置\h14.1.3數(shù)據(jù)表架構(gòu)設(shè)計\h14.1.4定義路由列表\h14.1.5編寫共用模板\h14.2注冊與登錄\h14.3博主資料信息\h14.4圖片墻功能\h14.5留言板功能\h14.6文章列表\h14.7文章正文內(nèi)容\h14.8Admin后臺系統(tǒng)\h14.8.1模型的數(shù)據(jù)管理\h14.8.2自定義Admin的登錄頁面\h14.8.3DjangoCKEditor生成文章編輯器\h14.9測試與部署\h14.9.1測試業(yè)務(wù)邏輯\h14.9.2上線部署\h第15章音樂網(wǎng)站平臺的設(shè)計與實現(xiàn)\h15.1項目設(shè)計與配置\h15.1.1項目架構(gòu)設(shè)計\h15.1.2功能配置\h15.1.3數(shù)據(jù)表架構(gòu)設(shè)計\h15.1.4定義路由列表\h15.1.5編寫共用模板\h15.2網(wǎng)站首頁\h15.3歌曲排行榜\h15.4歌曲搜索\h15.5歌曲播放與下載\h15.6歌曲點評\h15.7注冊與登錄\h15.8用戶中心\h15.9Admin后臺系統(tǒng)\h15.10自定義異常頁面\h15.11部署與運行\(zhòng)h15.11.1上線部署\h15.11.2網(wǎng)站試運行\(zhòng)h第16章基于前后端分離與微服務(wù)架構(gòu)的網(wǎng)站開發(fā)\h16.1Vue框架\h16.1.1Vue開發(fā)產(chǎn)品信息頁\h16.1.2Vue發(fā)送AJAX請求\h16.2Django開發(fā)API接口\h16.2.1簡化Django內(nèi)置功能\h16.2.2設(shè)置跨域訪問\h16.2.3使用路由視圖開發(fā)API接口\h16.2.4DRF框架開發(fā)API接口\h16.3微服務(wù)架構(gòu)\h16.3.1微服務(wù)實現(xiàn)原理\h16.3.2功能拆分\h16.3.3設(shè)計API網(wǎng)關(guān)\h16.3.4調(diào)試與運行\(zhòng)h16.4JWT認證\h16.4.1認識JWT\h16.4.2DRF的JWT\h16.5微服務(wù)注冊與發(fā)現(xiàn)\h16.5.1常用的服務(wù)注冊與發(fā)現(xiàn)框架\h16.5.2Consul的安裝與接口\h16.5.3Django與Consul的交互\h16.5.4服務(wù)的運行與部署\h16.5.5服務(wù)的負載均衡\h第17章Django項目上線部署\h17.1基于Windows部署Django\h17.1.1安裝IIS服務(wù)器\h17.1.2創(chuàng)建項目站點\h17.1.3配置靜態(tài)資源\h17.2基于Linux部署Django\h17.2.1安裝Linux虛擬機\h17.2.2安裝Python3\h17.2.3部署uWSGI服務(wù)器\h17.2.4安裝Nginx部署項目第10章Auth認證系統(tǒng)Django除了內(nèi)置的Admin后臺系統(tǒng)之外,還內(nèi)置了Auth認證系統(tǒng)。整個Auth認證系統(tǒng)可分為三大部分:用戶信息、用戶權(quán)限和用戶組,在數(shù)據(jù)庫中分別對應(yīng)數(shù)據(jù)表auth_user、auth_permission和auth_group。10.1內(nèi)置User實現(xiàn)用戶管理用戶管理是網(wǎng)站必備的功能之一,Django內(nèi)置的Auth認證系統(tǒng)不僅功能完善,而且具有靈活的擴展性,可以滿足多方面的開發(fā)需求。創(chuàng)建項目時,Django已默認使用內(nèi)置Auth認證系統(tǒng),在settings.py的INSTALLED_APPS、MIDDLEWARE和AUTH_PASSWORD_VALIDATORS中都能看到相關(guān)的配置信息。本節(jié)將使用內(nèi)置的Auth認證系統(tǒng)實現(xiàn)用戶注冊、登錄、修改密碼和注銷功能。在D盤下創(chuàng)建新的MyDjango項目,添加項目應(yīng)用user,并新建templates和static文件夾。在templates中放置模板文件user.html,在static中放置模板文件user.html所需的JS和CSS文件。項目的目錄結(jié)構(gòu)如圖10-1所示。圖10-1目錄結(jié)構(gòu)打開MyDjango的配置文件settings.py,將項目應(yīng)用user、模板文件夾templates和靜態(tài)資源文件夾static添加到Django的運行環(huán)境,配置信息如下:完成MyDjango的基本配置后,在PyCharm的Terminal下執(zhí)行數(shù)據(jù)遷移指令,項目內(nèi)置的數(shù)據(jù)表創(chuàng)建在MyDjango的db.sqlite3數(shù)據(jù)庫文件中。打開并查看db.sqlite3數(shù)據(jù)庫文件的數(shù)據(jù)表信息,如圖10-2所示。圖10-2數(shù)據(jù)表信息項目環(huán)境搭建成功后,在項目應(yīng)用user中創(chuàng)建urls.py文件,并分別在MyDjango文件夾的urls.py和user的urls.py中定義用戶注冊、登錄、修改密碼和注銷的路由信息,代碼如下:#MyDjango的urls.py
fromdjango.urlsimportpath,include
urlpatterns=[
path('',include(('user.urls','user'),namespace='user')),
]
#user的urls.py
fromdjango.urlsimportpath
from.viewsimport*
urlpatterns=[
path('login.html',loginView,name='login'),
path('register.html',registerView,name='register'),
path('setps.html',setpsView,name='setps'),
path('logout.html',logoutView,name='logout'),
]
項目應(yīng)用user定義了4條路由信息,分別代表用戶注冊、登錄、修改密碼和注銷,而4條路由所對應(yīng)的網(wǎng)頁信息都由模板文件user.html生成,因此在模板文件user.html中編寫以下代碼:完成項目的功能配置、路由設(shè)置和模板代碼編寫后,最后在user的views.py里定義視圖函數(shù)。首先定義視圖函數(shù)registerView,實現(xiàn)用戶注冊功能,代碼如下:視圖函數(shù)registerView對用戶請求進行判斷分析,如果當(dāng)前請求為GET請求,就調(diào)用模板文件user.html生成用戶注冊頁面;如果當(dāng)前請求為POST請求,就由內(nèi)置的Auth認證系統(tǒng)執(zhí)行用戶注冊過程,具體說明如下:(1)當(dāng)用戶在注冊頁面輸入賬號和密碼,并單擊“確定”按鈕后,程序?qū)⒈韱螖?shù)據(jù)提交到函數(shù)registerView中進行處理。(2)函數(shù)registerView首先獲取表單的數(shù)據(jù)內(nèi)容,根據(jù)獲取的數(shù)據(jù)來判斷Django內(nèi)置模型User是否存在相關(guān)的用戶信息。(3)如果用戶存在,就直接返回注冊頁面并提示用戶已存在。(4)如果用戶不存在,程序就使用內(nèi)置函數(shù)create_user對模型User進行用戶創(chuàng)建,函數(shù)create_user是模型User特有的函數(shù),該函數(shù)創(chuàng)建并保存一個is_active=True的User對象。其中,函數(shù)參數(shù)username不能為空,否則拋出ValueError異常;而模型User的其他字段可作為函數(shù)create_user的可選參數(shù),模型User的字段可在數(shù)據(jù)表auth_user中查看,如email、first_name和password等。如果沒有設(shè)置參數(shù)password,模型User就調(diào)用set_unusable_password()為當(dāng)前用戶創(chuàng)建一個隨機密碼。Django的內(nèi)置模型User一共定義了11個字段,各個字段的含義說明如表10-1所示。表10-1User模型各個字段的說明運行MyDjango項目,在瀏覽器上訪問:8000/register.html,在用戶注冊表單中填寫賬號密碼,單擊“確定”按鈕即可完成用戶注冊。打開數(shù)據(jù)表auth_user就能看到新建的用戶信息,如圖10-3所示。圖10-3數(shù)據(jù)表auth_user下一步實現(xiàn)用戶登錄過程,同時也能驗證視圖函數(shù)registerView實現(xiàn)的用戶注冊功能是否正常。我們在user的views.py中定義視圖函數(shù)loginView,函數(shù)代碼如下:視圖函數(shù)loginView與registerView的實現(xiàn)過程有相似之處,它也是對用戶請求進行判斷分析,如果當(dāng)前請求為GET請求,就調(diào)用模板文件user.html生成用戶登錄頁面;如果當(dāng)前請求為POST請求,就由內(nèi)置的Auth認證系統(tǒng)執(zhí)行用戶登錄過程,具體說明如下:(1)當(dāng)函數(shù)loginView收到POST請求并獲取表單的數(shù)據(jù)后,根據(jù)表單數(shù)據(jù)判斷用戶是否存在。如果用戶存在,就對用戶賬號和密碼進行驗證處理,由內(nèi)置函數(shù)authenticate完成驗證過程,若驗證成功,則返回模型Uesr的用戶對象user,否則返回None。(2)從用戶對象user的is_active字段來判斷當(dāng)前用戶狀態(tài)是否被激活,如果字段is_active的值為1,就說明當(dāng)前用戶處于已激活狀態(tài),可執(zhí)行用戶登錄。(3)執(zhí)行用戶登錄,由內(nèi)置函數(shù)login完成登錄過程。函數(shù)login接收兩個參數(shù),第一個是request對象,來自視圖函數(shù)的參數(shù)request;第二個是user對象,來自函數(shù)authenticate返回的對象user。運行MyDjango項目,在瀏覽器上訪問:8000/login.html,在用戶登錄表單中填寫新建的admin用戶信息,單擊“確定”按鈕即可完成用戶登錄。我們可以在數(shù)據(jù)表auth_user中查看admin用戶的登錄時間來驗證登錄是否成功,如圖10-4所示。圖10-4數(shù)據(jù)表auth_user密碼修改頁面是根據(jù)已有的用戶信息進行密碼修改。我們在user的views.py中定義視圖函數(shù)setpsView,函數(shù)代碼如下:密碼修改頁面相比注冊和登錄頁面多出了一個文本輸入框,該文本輸入框由模板上下文password2控制顯示。當(dāng)password2為True時,文本輸入框?qū)@示到頁面上,如圖10-5所示。圖10-5修改密碼頁面視圖函數(shù)setpsView的處理邏輯與用戶注冊、登錄大致相同,函數(shù)處理邏輯說明如下:(1)當(dāng)函數(shù)setpsView收到POST請求后,程序獲取表單的數(shù)據(jù)內(nèi)容,然后在表單數(shù)據(jù)中查找模型User的用戶信息。(2)如果用戶存在,就由內(nèi)置函數(shù)authenticate驗證用戶的賬號和密碼是否正確。若驗證成功,則返回對象user,再由對象user使用內(nèi)置函數(shù)set_password修改當(dāng)前用戶的密碼,最后保存修改后的對象user,從而實現(xiàn)密碼修改。(3)如果用戶不存在,就直接返回密碼修改頁面并提示用戶不存在。密碼修改主要由內(nèi)置函數(shù)set_password實現(xiàn),而函數(shù)set_password是在內(nèi)置函數(shù)make_password的基礎(chǔ)上進行封裝而來的。Django默認使用pbkdf2_sha256方式存儲和管理用戶密碼,而內(nèi)置函數(shù)make_password用于實現(xiàn)用戶密碼的加密處理,并且該函數(shù)可以脫離Auth認證系統(tǒng)單獨使用,比如對某些特殊數(shù)據(jù)進行加密處理等。在user的views.py中定義視圖函數(shù)setpsView2,它使用函數(shù)make_password實現(xiàn)密碼修改,代碼如下:視圖函數(shù)setpsView2與setpsView的處理邏輯相同,只不過兩者修改密碼的方法有所不同。除了內(nèi)置函數(shù)make_password之外,還有內(nèi)置函數(shù)check_password,該函數(shù)是對加密前的密碼與加密后的密碼進行驗證匹配,判斷兩者是否為同一個密碼。在PyCharm的Terminal中開啟Django的Shell模式,函數(shù)make_password和check_password的使用方法如下:D:\MyDjango>pythonmanage.pyshell
>>>fromdjango.contrib.auth.hashersimportmake_password
>>>fromdjango.contrib.auth.hashersimportcheck_password
>>>ps="123456"
>>>dj_ps=make_password(ps,None,'pbkdf2_sha256')
>>>ps_bool=check_password(ps,dj_ps)
>>>ps_bool
True
用戶注銷是Auth認證系統(tǒng)較為簡單的功能,只需調(diào)用內(nèi)置函數(shù)logout即可實現(xiàn)。函數(shù)logout的參數(shù)request代表當(dāng)前用戶的請求對象,來自于視圖函數(shù)的參數(shù)request。因此,視圖函數(shù)logoutView的代碼如下:#用戶注銷,退出登錄
deflogoutView(request):
logout(request)
returnHttpResponse('注銷成功')
綜上所述,整個MyDjango項目定義了4條路由信息,分別實現(xiàn)用戶注冊、登錄、修改密碼和注銷功能。由Auth認證系統(tǒng)的內(nèi)置模型User實現(xiàn)用戶信息管理,開發(fā)者只需調(diào)用內(nèi)置函數(shù)即可實現(xiàn)功能開發(fā)。10.2發(fā)送郵件實現(xiàn)密碼找回在10.1節(jié)中,密碼修改是在用戶知道密碼的情況下實現(xiàn)的,而在日常應(yīng)用中,還有一種是在用戶忘記密碼的情況下實現(xiàn)密碼修改,也稱為密碼找回。密碼找回首先需要對用戶賬號進行驗證,確認該賬號是當(dāng)前用戶所擁有的,驗證成功才能為用戶重置密碼。用戶驗證方式主要有手機驗證碼和郵件驗證碼,因此本節(jié)使用Django內(nèi)置的郵件功能發(fā)送驗證碼,從而實現(xiàn)密碼找回功能。在實現(xiàn)郵件發(fā)送功能之前,我們需要對郵箱進行相關(guān)配置,以QQ郵箱為例,在QQ郵箱的設(shè)置中找到賬戶設(shè)置,在賬戶設(shè)置中找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服務(wù),然后開啟POP3/SMTP服務(wù),如圖10-6所示。圖10-6開啟POP3/SMTP服務(wù)開啟服務(wù)成功后,QQ郵箱會返回一個客戶端授權(quán)密碼,該密碼是用于登錄第三方郵件客戶端的專用密碼,切記保存授權(quán)密碼,該密碼在開發(fā)過程中需要使用。如果QQ開啟了登錄保護,就必須取消登錄保護,否則Django無法使用POP3/SMTP服務(wù)發(fā)送郵件驗證碼。下一步在Django里使用POP3/SMTP服務(wù)發(fā)送郵件驗證碼,以10.1節(jié)的MyDjango為例,在配置文件settings.py中設(shè)置郵件配置信息,配置信息如下:#郵件配置信息
EMAIL_USE_SSL=True
#郵件服務(wù)器,如果是163,就改成
EMAIL_HOST=''
#郵件服務(wù)器端口
EMAIL_PORT=465
#發(fā)送郵件的賬號
EMAIL_HOST_USER='185231027@'
#SMTP服務(wù)密碼
EMAIL_HOST_PASSWORD='odnwdcwsphzi'
DEFAULT_FROM_EMAIL=EMAIL_HOST_USER
郵件配置一共設(shè)置6個配置屬性,這些屬性是配置郵件發(fā)送方的服務(wù)器信息,配置屬性的值是由郵件服務(wù)器決定的。每個配置屬性的作用說明如下:●EMAIL_USE_SSL:Django與郵件服務(wù)器的連接方式是否設(shè)為SSL模式。●EMAIL_HOST:設(shè)置服務(wù)器類型,QQ郵箱分為SMTP服務(wù)器和POP3服務(wù)器?!馝MAIL_PORT:設(shè)置服務(wù)器端口號,若使用SMTP服務(wù)器,則端口應(yīng)為465或587?!馝MAIL_HOST_USER:發(fā)送郵件的賬號,該賬號必須開啟POP3/SMTP服務(wù)。●EMAIL_HOST_PASSWORD:客戶端授權(quán)密碼,即圖10-6開啟服務(wù)后所獲得的授權(quán)碼?!馜EFAULT_FROM_EMAIL:設(shè)置默認發(fā)送郵件的賬號。完成郵件相關(guān)配置后,在MyDjango的urls.py和user的urls.py中定義路由信息,分別設(shè)置Admin后臺系統(tǒng)的路由和定義密碼找回的路由,代碼如下:#MyDjango的urls.py
fromdjango.urlsimportpath,include
fromdjango.contribimportadmin
urlpatterns=[
path('admin/',admin.site.urls),
path('',include(('user.urls','user'),namespace='user')),
]
#user的urls.py
fromdjango.urlsimportpath
from.viewsimport*
urlpatterns=[
path('',findpsView,name='findps'),
]
設(shè)置Admin后臺系統(tǒng)的路由可以驗證用戶密碼修改后是否能正常登錄Admin后臺系統(tǒng)。接著修改模板文件user.html的用戶表單,代碼如下:模板文件user.html設(shè)置了4個模板上下文,分別為password、VCodeInfo、tips和button,每個上下文的說明如下:●password控制密碼文本框是否顯示在網(wǎng)頁上,數(shù)據(jù)類型為布爾型?!馰CodeInfo控制驗證碼文本框是否顯示在網(wǎng)頁上,數(shù)據(jù)類型為布爾型?!駎ips是根據(jù)用戶操作和賬號驗證設(shè)置的信息提示,信息內(nèi)容分別為:“驗證碼已發(fā)送”“用戶XXX不存在”“密碼已重置”和“驗證碼錯誤,請重新獲取”?!馼utton可以改變表單提交按鈕的文本內(nèi)容,內(nèi)容分別為:“獲取驗證碼”和“重置密碼”。最后在user的views.py中定義視圖函數(shù)findpsView,該函數(shù)實現(xiàn)3個功能:發(fā)送郵件驗證碼、驗證郵件驗證碼和修改密碼,具體代碼如下:由于視圖函數(shù)findpsView實現(xiàn)3個不同的功能,因此從功能使用的角度分析視圖函數(shù)findpsView。運行MyDjango并在瀏覽器上訪問:8000,視圖函數(shù)findpsView觸發(fā)GET請求,調(diào)用模板文件user.html生成網(wǎng)頁表單,在網(wǎng)頁表單上輸入用戶賬號admin并單擊“獲取驗證碼”按鈕,如圖10-7所示。圖10-7獲取驗證碼當(dāng)輸入用戶名并單擊“獲取驗證碼”按鈕時,瀏覽器向Django發(fā)送POST請求,視圖函數(shù)findpsView首先根據(jù)用戶輸入的用戶名在模型User里進行數(shù)據(jù)查找,然后判斷用戶名是否存在,若不存在,則會生成提示信息,如圖10-8所示。圖10-8用戶不存在如果用戶存在,就繼續(xù)判斷會話Session的VCode是否存在。若不存在,則視圖函數(shù)findpsView通過發(fā)送郵件的方式將驗證碼發(fā)送到用戶郵箱,實現(xiàn)過程如下:●設(shè)置模板上下文button、tips、password和VCodeInfo的值,在網(wǎng)頁上生成提示信息、密碼輸入框和驗證碼輸入框。●驗證碼是使用random模塊隨機生成長度為4位的整數(shù),然后將驗證碼寫入會話Session的VCode,其作用是與用戶輸入的驗證碼進行匹配?!襦]件發(fā)送是由內(nèi)置函數(shù)email_user實現(xiàn)的,該方法是模型User特有的方法之一,只適用于模型User。●用戶郵箱信息來自于模型User的字段email,如果當(dāng)前用戶的郵箱信息為空,Django就無法發(fā)送郵件。郵件發(fā)送如圖10-9所示。圖10-9郵件發(fā)送用戶接收到驗證碼之后,可以在網(wǎng)頁上輸入用戶名、重置密碼和驗證碼,然后單擊“重置密碼”按鈕,這時將會觸發(fā)POST請求,函數(shù)findpsView獲取用戶輸入的驗證碼并與會話Session的VCode進行對比,如果兩者不符合,就說明用戶輸入的驗證碼與郵件中的驗證碼無法匹配,系統(tǒng)提示驗證碼錯誤,如圖10-10所示。圖10-10驗證碼錯誤若用戶輸入的驗證碼與會話Session的VCode匹配符合,則程序?qū)?zhí)行密碼修改。首先獲取用戶輸入的密碼,然后使用函數(shù)make_password對密碼進行加密處理并保存在模型User中,最后刪除會話Session的VCode,否則會話Session的VCode一直存在,在下次獲取驗證碼時,程序就不會執(zhí)行郵件發(fā)送功能。運行結(jié)果如圖10-11所示。圖10-11運行結(jié)果上述例子是使用內(nèi)置函數(shù)email_user發(fā)送郵件驗證碼,除此之外,Django還提供了多種郵件發(fā)送方法。我們在Django的Shell模式下進行講解,代碼如下:D:\MyDjango>pythonmanage.pyshell
#使用send_mail實現(xiàn)郵件發(fā)送
>>>fromdjango.core.mailimportsend_mail
>>>fromdjango.confimportsettings
#獲取settings.py的配置信息
>>>from_email=settings.DEFAULT_FROM_EMAIL
>>>sending=['554301449@']
#發(fā)送郵件,接收郵件以列表表示,說明可設(shè)置多個接收對象
>>>send_mail('Django','Django',from_email,sending)
#使用send_mass_mail實現(xiàn)多封郵件同時發(fā)送
>>>fromdjango.core.mailimportsend_mass_mail
>>>message1=('Django','Django',from_email,sending)
>>>message2=('Django','Django',from_email,sending)
>>>send_mass_mail((message1,message2),fail_silently=False)
#使用EmailMultiAlternatives實現(xiàn)郵件發(fā)送
>>>fromdjango.core.mailimportEmailMultiAlternatives
>>>content='<p>這是一封<h3>重要的</h3>郵件。</p>'
>>>msg=EmailMultiAlternatives('MyDjango',content,from_email,sending)
#將正文設(shè)置為HTML格式
>>>msg.content_subtype='html'
#attach_alternative對正文內(nèi)容進行補充和添加
>>>msg.attach_alternative('<h3>Django</h3>','text/html')
#添加附件(可選)
>>>msg.attach_file('D://attachfile.csv')
#發(fā)送
>>>msg.send()
上述代碼分別講述了send_mail、send_mass_mail和EmailMultiAlternatives的使用方法,三者之間的對比說明如下:●使用send_mail每次發(fā)送郵件都會建立一個新的連接,如果發(fā)送多封郵件,就需要建立多個連接?!駍end_mass_mail是建立單個連接發(fā)送多封郵件,所以一次性發(fā)送多封郵件時,send_mass_mail要優(yōu)于send_mail?!馝mailMultiAlternatives比前兩者更為個性化,可以將郵件正文內(nèi)容設(shè)為HTML格式的,也可以在郵件上添加附件,滿足多方面的開發(fā)需求。10.3模型User的擴展與使用在開發(fā)過程中,模型User的字段可能滿足不了復(fù)雜的開發(fā)需求?,F(xiàn)在大多數(shù)網(wǎng)站的用戶信息都有用戶的手機號碼、QQ號碼和微信賬號等一系列個人信息。為了滿足各種需求,Django提供了以下4種模型擴展的方法。代理模型:這是一種模型繼承,這種模型在數(shù)據(jù)庫中無須創(chuàng)建新數(shù)據(jù)表。一般用于改變現(xiàn)有模型的行為方式,如增加新方法函數(shù)等,并且不影響數(shù)據(jù)表的結(jié)構(gòu)。如果不需要在數(shù)據(jù)表存儲額外的信息,只是增加模型User的操作方法或更改模型的查詢方式,那么可以使用代理模型擴展模型User。Profile擴展模型User:當(dāng)存儲的信息與模型User相關(guān),而且不改變模型User的內(nèi)置方法時,可定義新的模型MyUser,并設(shè)置某個字段為OneToOneField,這樣能與模型User形成一對一關(guān)系,該方法稱為用戶配置(UserProfile)。AbstractBaseUser擴展模型User:當(dāng)模型User的內(nèi)置方法不符合開發(fā)需求時,可使用該方法對模型User重新自定義設(shè)計,該方法對模型User和數(shù)據(jù)表結(jié)構(gòu)造成較大影響。AbstractUser擴展模型User:如果模型User的內(nèi)置方法符合開發(fā)需求,在不改變這些函數(shù)方法的情況下,添加模型User的額外字段,可通過AbstractUser方式替換原有的模型User。上述4種方法各有優(yōu)缺點,一般情況下,建議使用AbstractUser擴展模型User,因為該方式對原有模型User影響較小而且無須額外創(chuàng)建數(shù)據(jù)表。在講述如何擴展模型User之前,首先深入了解模型User的定義過程。在PyCharm里打開模型User的源碼文件,如圖10-12所示。圖10-12模型User的源碼文件模型User繼承父類AbstractUser,而AbstractUser繼承父類AbstractBaseUser和PermissionsMixin,因此模型User的繼承關(guān)系如圖10-13所示。圖10-13模型User的繼承關(guān)系從圖10-13得知,模型User的字段和方法是由父類AbstractUser、AbstractBaseUser和PermissionsMixin定義的,模型字段已在10.1節(jié)的表10-1列舉說明,本節(jié)只列舉說明模型User的內(nèi)置方法,分別說明如下:●get_full_name():由AbstractUser定義,獲取用戶的全名,即字段first_name與last_name的組合值?!駁et_short_name():由AbstractUser定義,獲取模型字段first_name的值?!馿mail_user():由AbstractUser定義,發(fā)送郵件。參數(shù)subject設(shè)置郵件標(biāo)題;參數(shù)message設(shè)置郵件內(nèi)容;參數(shù)from_email設(shè)置發(fā)送郵件的賬號,即配置文件settings.py的DEFAULT_FROM_EMAIL?!駍ave():由AbstractBaseUser定義,定義模型的數(shù)據(jù)保存方式?!駁et_username():由AbstractBaseUser定義,獲取當(dāng)前用戶的賬號信息,即模型字段username?!駍et_password():由AbstractBaseUser定義,更改當(dāng)前用戶的密碼,即更改模型字段password?!馽heck_password():由AbstractBaseUser定義,驗證加密前的密碼與加密后的密碼是否相同?!駁et_session_auth_hash():由AbstractBaseUser定義,獲取模型字段password的HMAC,在更改密碼時可使當(dāng)前用戶的登錄狀態(tài)失效?!駍et_unusable_password():由AbstractBaseUser定義,標(biāo)記用戶尚未設(shè)置密碼?!駂as_usable_password():由AbstractBaseUser定義,檢測用戶是否尚未設(shè)置密碼?!駁et_group_permissions():由PermissionsMixin定義,獲取當(dāng)前用戶所在用戶組的權(quán)限?!駁et_all_permissions():由PermissionsMixin定義,獲取當(dāng)前用戶所擁有的權(quán)限?!駂as_perm():由PermissionsMixin定義,判斷當(dāng)前用戶是否具有某個權(quán)限,參數(shù)perm代表權(quán)限的名稱,以字符串表示?!駂as_perms():由PermissionsMixin定義,判斷當(dāng)前用戶是否具有多個權(quán)限,參數(shù)perm_list代表多個權(quán)限的集合,以列表表示。●has_module_perms():由PermissionsMixin定義,判斷當(dāng)前用戶是否具有某個項目應(yīng)用的所有權(quán)限,參數(shù)app_label代表項目應(yīng)用的名稱。下一步講述如何使用AbstractUser擴展模型User。以MyDjango為例,打開項目的數(shù)據(jù)庫db.sqlite3文件,清除數(shù)據(jù)庫所有的數(shù)據(jù)表,在user的models.py中定義模型MyUser,代碼如下:#user的models.py
fromdjango.dbimportmodels
fromdjango.contrib.auth.modelsimportAbstractUser
classMyUser(AbstractUser):
qq=models.CharField('QQ號碼',max_length=16)
weChat=models.CharField('微信賬號',max_length=100)
mobile=models.CharField('手機號碼',max_length=11)
#設(shè)置返回值
def__str__(self):
returnself.username
模型MyUser繼承AbstractUser類,AbstractUser類是模型User的父類,因此模型MyUser也具有模型User的全部字段。在執(zhí)行數(shù)據(jù)遷移之前,必須在項目的settings.py中配置相關(guān)信息,配置信息如下:#settings.py
AUTH_USER_MODEL='user.MyUser'
配置信息是將內(nèi)置模型User替換成自定義的模型MyUser,若沒有設(shè)置配置信息,則在創(chuàng)建數(shù)據(jù)表的時候,Django分別創(chuàng)建數(shù)據(jù)表auth_user和user_myuser,這樣模型MyUser無法取代內(nèi)置模型User。在PyCharm的Terminal下執(zhí)行數(shù)據(jù)遷移,代碼如下:D:\MyDjango>pythonmanage.pymakemigrations
Migrationsfor'user':
user\migrations\0001_initial.py
-CreatemodelMyUser
D:\MyDjango>pythonmanage.pymigrate
完成數(shù)據(jù)遷移后,打開數(shù)據(jù)庫查看數(shù)據(jù)表信息,可以發(fā)現(xiàn)內(nèi)置模型User的數(shù)據(jù)表auth_user改為數(shù)據(jù)表user_myuser,并且數(shù)據(jù)表user_myuser的字段除了具有內(nèi)置模型User的字段之外,還額外增加了自定義的字段,如圖10-14所示。圖10-14數(shù)據(jù)表user_myuser使用AbstractUser擴展模型User的實質(zhì)是重新自定義模型User,將內(nèi)置模型User替換成自定義的模型MyUser,替換過程可分為兩個步驟?!穸x新的模型MyUser,該模型必須繼承AbstractUser類,在模型MyUser里定義的字段為擴展字段?!裨陧椖康呐渲梦募ettings.py中配置AUTH_USER_MODEL信息,在數(shù)據(jù)遷移時,將內(nèi)置模型User替換成自定義的模型MyUser。完成模型MyUser的自定義及數(shù)據(jù)遷移后,接著探討模型MyUser與內(nèi)置模型User在開發(fā)過程中是否存在使用上的差異。首先使用Django內(nèi)置命令pythonmanage.pycreatesuperuser創(chuàng)建超級管理員并登錄Admin后臺系統(tǒng),如圖10-15所示。圖10-15Admin后臺系統(tǒng)從圖10-15中發(fā)現(xiàn),認證與授權(quán)沒有顯示用戶信息表,因為模型MyUser是在user的models.py中定義的。若將模型MyUser展示在后臺系統(tǒng),則可以在user的admin.py和初始化文件__init__.py中定義相關(guān)的數(shù)據(jù)對象,代碼如下:重啟MyDjango項目并再次進入Admin后臺系統(tǒng),可以在頁面上看到模型MyUser所生成的“用戶”,如圖10-16所示。圖10-16模型MyUser的用戶鏈接從用戶數(shù)據(jù)列表頁進入用戶數(shù)據(jù)修改頁或用戶數(shù)據(jù)新增頁的時候,發(fā)現(xiàn)用戶數(shù)據(jù)修改頁或用戶數(shù)據(jù)新增頁出現(xiàn)了用戶的手機號碼、QQ號碼和微信賬號的文本輸入框,這是由MyUserAdmin重寫屬性fieldsets實現(xiàn)的,如圖10-17所示。圖10-17修改用戶數(shù)據(jù)admin.py定義的MyUserAdmin繼承自UserAdmin,UserAdmin是內(nèi)置模型User的Admin數(shù)據(jù)對象,換句話說,MyUserAdmin通過繼承UserAdmin并重寫父類的某些屬性和方法能使自定義模型MyUser展示在Admin后臺系統(tǒng)。UserAdmin的定義過程可以在Django源碼文件django\contrib\auth\admin.py中查看。除了UserAdmin之外,還可以繼承內(nèi)置模型User定義的表單類。內(nèi)置表單類可以在源碼文件django\contrib\auth\forms.py中查看,從源碼中發(fā)現(xiàn),forms.py定義了多個內(nèi)置表單類,其說明如下:●UserCreationForm:表單字段為username、password1和password2,創(chuàng)建新的用戶信息?!馯serChangeForm:表單字段為password和模型User所有字段,修改已有的用戶信息?!馎uthenticationForm:表單字段為username和password,用戶登錄時所觸發(fā)的認證功能?!馪asswordResetForm:表單字段為email,將重置密碼通過發(fā)送郵件的方式實現(xiàn)密碼找回。●SetPasswordForm:表單字段為password1和password2,修改或新增用戶密碼?!馪asswordChangeForm:表單字段為old_password、new_password1和new_password2,繼承SetPasswordForm,如果是修改密碼,就需要對舊密碼進行驗證?!馎dminPasswordChangeForm:表單字段為password1和password2,用于Admin后臺修改用戶密碼。從上述的內(nèi)置表單類發(fā)現(xiàn),這些表單都是在內(nèi)置模型User的基礎(chǔ)上實現(xiàn)的,但這些表單類不一定適用于自定義模型MyUser。但我們可以自定義模型MyUser的表單類,并繼承上述的內(nèi)置表單類,從而使定義的表單類適用于模型MyUser。以內(nèi)置表單類UserCreationForm為例,使用表單類UserCreationForm實現(xiàn)用戶注冊功能。在user中創(chuàng)建form.py文件,并在文件下編寫以下代碼:自定義表單類MyUserCreationForm繼承表單類UserCreationForm,并且重寫Meta的屬性model和fields,分別設(shè)置表單類綁定的模型和字段。最后在MyDjango的urls.py、user的urls.py、views.py和模板文件user.html中實現(xiàn)用戶注冊功能,代碼如下:視圖函數(shù)registerView使用自定義表單類MyUserCreationForm實現(xiàn)用戶注冊功能,實現(xiàn)過程如下:(1)在瀏覽器上訪問:8000時,視圖函數(shù)將表單類MyUserCreationForm實例化并傳遞給模板文件user.html,在瀏覽器上生成用戶注冊頁面。(2)輸入用戶信息并單擊“注冊”按鈕,視圖函數(shù)registerView收到POST請求,將表單數(shù)據(jù)交給表單類MyUserCreationForm處理并生成user對象。(3)驗證user對象的數(shù)據(jù)信息,如果驗證成功,就將數(shù)據(jù)保存到數(shù)據(jù)表user_myuser中,并在網(wǎng)頁上提示“注冊成功”;若驗證失敗,則在網(wǎng)頁上提示“注冊失敗”并清空表單數(shù)據(jù)。(4)注冊用戶的時候,表單類MyUserCreationForm對密碼的安全強度有嚴(yán)格的要求,如9.4節(jié)的圖9-19所示,建議讀者設(shè)置安全強度較高的密碼,密碼過于簡單會無法完成注冊。10.4權(quán)限的設(shè)置與使用用戶權(quán)限是對不同用戶設(shè)置不同的功能使用權(quán)限,而每個功能主要以模型來劃分。以10.3節(jié)的MyDjango項目為例,在Admin后臺系統(tǒng)的用戶數(shù)據(jù)修改頁或用戶數(shù)據(jù)新增頁可以查看并設(shè)置用戶權(quán)限,如圖10-18所示。圖10-18用戶權(quán)限在圖10-18的左側(cè)列表框中列出了整個項目的用戶權(quán)限,每個權(quán)限以“項目應(yīng)用|模型|模型使用權(quán)限”的格式表示,以user|用戶|Canadduser為例,說明如下:●user是項目應(yīng)用user的名稱?!裼脩羰琼椖繎?yīng)用user定義的模型MyUser?!馛anadduser是模型MyUser新增數(shù)據(jù)的權(quán)限。當(dāng)執(zhí)行數(shù)據(jù)遷移時,每個模型默認擁有增(Add)、改(Change)、刪(Delete)和查(View)權(quán)限。數(shù)據(jù)遷移成功后,可以在數(shù)據(jù)庫中查看數(shù)據(jù)表auth_permission的數(shù)據(jù)信息,每行數(shù)據(jù)代表項目中某個模型的某個權(quán)限,如圖10-19所示。圖10-19數(shù)據(jù)表auth_permission設(shè)置用戶權(quán)限實質(zhì)上是對數(shù)據(jù)表user_myuser和auth_permission之間的數(shù)據(jù)設(shè)置多對多關(guān)系。首先需要了解用戶、用戶權(quán)限和用戶組三者之間的關(guān)系,以MyDjango的數(shù)據(jù)表為例,如圖10-20所示。圖10-20MyDjango的數(shù)據(jù)表信息從整個項目的數(shù)據(jù)表看到,用戶、用戶權(quán)限和用戶組分別對應(yīng)數(shù)據(jù)表user_myuser、auth_permission和auth_group。無論是設(shè)置用戶權(quán)限、設(shè)置用戶所屬用戶組或者設(shè)置用戶組的權(quán)限,它們的本質(zhì)都是對兩個數(shù)據(jù)表之間的數(shù)據(jù)建立多對多的數(shù)據(jù)關(guān)系,說明如下:●數(shù)據(jù)表user_myuser_user_permissions:管理數(shù)據(jù)表user_myuser和auth_permission之間的多對多關(guān)系,設(shè)置用戶所擁有的權(quán)限?!駭?shù)據(jù)表user_myuser_groups:管理數(shù)據(jù)表user_myuser和auth_group之間的多對多關(guān)系,設(shè)置用戶所在的用戶組?!駭?shù)據(jù)表auth_group_permissions:管理數(shù)據(jù)表auth_group和auth_permission之間的多對多關(guān)系,設(shè)置用戶組所擁有的權(quán)限。在設(shè)置用戶權(quán)限時,如果用戶的角色是超級管理員,該用戶就無須設(shè)置權(quán)限,因為超級管理員已默認具備整個系統(tǒng)的所有權(quán)限,而設(shè)置用戶權(quán)限只適用于非超級管理員的用戶。我們在Admin后臺系統(tǒng)創(chuàng)建普通用戶root,然后在PyCharm的Terminal下開啟Django的Shell模式實現(xiàn)用戶權(quán)限設(shè)置,代碼如下:D:\MyDjango>pythonmanage.pyshell
#導(dǎo)入模型MyUser
>>>fromuser.modelsimportMyUser
#查詢用戶信息
>>>user=MyUser.objects.filter(username='root')[0]
#判斷當(dāng)前用戶是否具有用戶新增的權(quán)限
#user.add_myuser為固定寫法
#user為項目應(yīng)用的名稱
#add_myuser來自數(shù)據(jù)表auth_permission的字段codename
>>>user.has_perm('user.add_myuser')
False
#導(dǎo)入模型Permission
>>>fromdjango.contrib.auth.modelsimportPermission
#在權(quán)限管理表獲取權(quán)限add_myuser的數(shù)據(jù)對象permission
>>>p=Permission.objects.filter(codename='add_myuser')[0]
#對當(dāng)前用戶對象user設(shè)置權(quán)限add_myuser
#user_permissions是多對多的模型字段
#該字段由內(nèi)置模型User的父類PermissionsMixin定義
>>>user.user_permissions.add(p)
#再次判斷當(dāng)前用戶是否具有用戶新增的權(quán)限
>>>user=MyUser.objects.filter(username='root')[0]
>>>user.has_perm('user.add_myuser')
True
上述代碼首先查詢用戶名為root的用戶是否具備用戶新增的權(quán)限,然后對該用戶設(shè)置用戶新增的權(quán)限,設(shè)置方式是由多對多的模型字段user_permissions調(diào)用add方法實現(xiàn)的。打開數(shù)據(jù)表user_myuser_user_permissions可以看到新增了一行數(shù)據(jù),如圖10-21所示。圖10-21數(shù)據(jù)表user_myuser_user_permissions從圖10-21看到,表字段myuser_id和permission_id分別是數(shù)據(jù)表user_myuser和auth_permission的主鍵,每一行數(shù)據(jù)代表某個用戶具有某個模型的某個操作權(quán)限。除了添加權(quán)限之外,還可以對用戶的權(quán)限進行刪除和查詢,代碼如下:#導(dǎo)入模型MyUser
>>>fromuser.modelsimportMyUser
#導(dǎo)入模型Permission
>>>fromdjango.contrib.auth.modelsimportPermission
#查詢用戶信息
>>>user=MyUser.objects.filter(username='root')[0]
#查詢用戶新增的權(quán)限
>>>p=Permission.objects.filter(codename='add_myuser')[0]
#刪除某條權(quán)限
>>>user.user_permissions.remove(p)
#判斷是否已刪除權(quán)限,若為False,則說明刪除成功
#函數(shù)has_perm用于判斷用戶是否擁有權(quán)限
>>>user.has_perm('user.add_myuser')
False
#清空當(dāng)前用戶全部權(quán)限
>>>user.user_permissions.clear()
#獲取當(dāng)前用戶所擁有的權(quán)限信息
#將上述刪除的權(quán)限添加到數(shù)據(jù)表再查詢
>>>user.user_permissions.add(p)
#查詢數(shù)據(jù)表user_myuser_user_permissions的數(shù)據(jù)
#查詢方式是使用ORM框架的API方法
>>>user.user_permissions.values()
10.5自定義用戶權(quán)限一般情況下,每個模型默認擁有增(Add)、改(Change)、刪(Delete)和查(View)權(quán)限。但實際開發(fā)中可能要對某個模型設(shè)置特殊權(quán)限,比如QQ音樂只允許會員播放高質(zhì)音樂。為了解決這種開發(fā)需求,在定義模型時,可以在模型的屬性Meta中設(shè)置自定義權(quán)限。以10.3節(jié)的MyDjango項目為例,對user的模型MyUser重新定義,代碼如下:模型MyUser的Meta繼承父類AbstractUser的Meta,并且新增permissions屬性,這樣就能創(chuàng)建用戶權(quán)限,模型MyUser的Meta必須繼承父類AbstractUser的Meta,因為AbstractUser的Meta定義屬性verbose_name、verbose_name_plural和abstract。新增屬性permissions以元組或列表的數(shù)據(jù)格式表示,元組或列表的每個元素代表一個權(quán)限,每個權(quán)限以元組或列表表示。一個權(quán)限中含有兩個元素,如上述的('vip_myuser','Canvipuser'),vip_myuser和Canvipuser分別是數(shù)據(jù)表auth_permission的codename和name字段。下一步在數(shù)據(jù)庫中清除MyDjango原有的數(shù)據(jù)表,并在PyCharm的Terminal中重新執(zhí)行數(shù)據(jù)遷移,代碼如下:D:\MyDjango>pythonmanage.pymakemigrations
Migrationsfor'user':
user\migrations\0001_initial.py
-CreatemodelMyUser
D:\MyDjango>pythonmanage.pymigrate
數(shù)據(jù)遷移執(zhí)行完成后,在數(shù)據(jù)庫中打開數(shù)據(jù)表auth_permission,可以找到自定義權(quán)限vip_myuser,如圖10-22所示。圖10-22數(shù)據(jù)表auth_permission10.6設(shè)置網(wǎng)頁的訪問權(quán)限通過前面的學(xué)習(xí),相信大家對Django的內(nèi)置權(quán)限功能有了一定的了解。本節(jié)將結(jié)合示例講述如何在網(wǎng)頁中設(shè)置用戶的訪問權(quán)限,以10.5節(jié)的MyDjango項目為例,確保項目應(yīng)用user已定義模型MyUser,并且數(shù)據(jù)表auth_permission已記錄權(quán)限vip_myuser的數(shù)據(jù)信息。我們在MyDjango的項目應(yīng)用user里實現(xiàn)用戶注冊、登錄和注銷功能,并且增加用戶中心,用于檢驗用戶是否具有vip_myuser權(quán)限。在編寫代碼之前,需要對MyDjango的目錄結(jié)構(gòu)進行調(diào)整,在templates文件夾放置模板文件info.html,在static文件夾放置模板文件的靜態(tài)資源,并且user的form.py文件已定義MyUserCreationForm表單類(定義過程可回顧10.3節(jié)),用于實現(xiàn)用戶注冊和登錄功能。下一步實現(xiàn)用戶注冊、登錄、注銷和用戶中心頁,分別在MyDjango的urls.py和user的urls.py中定義路由信息,代碼如下:#MyDjango的urls.py
fromdjango.urlsimportpath,include
fromdjango.contribimportadmin
urlpatterns=[
path('admin/',admin.site.urls),
path('',include(('user.urls','user'),namespace='user')),
]
#user的urls.py
fromdjango.urlsimportpath
from.viewsimport*
urlpatterns=[
#用戶注冊
path('',registerView,name='register'),
#用戶登錄
path('login.html',loginView,name='login'),
#用戶注銷
path('logout.html',logoutView,name='logout'),
#用戶中心
path('info.html',infoView,name='info')
]
項目應(yīng)用user的urls.py中定義了4條路由信息,它們實現(xiàn)了一個簡單的操作流程,流程順序為用戶注冊→用戶登錄→用戶中心→用戶注銷。然后在user的views.py中定義相關(guān)的視圖函數(shù),代碼如下:上述代碼分別定義視圖函數(shù)registerView、loginView、logoutView和infoView,函數(shù)之間通過網(wǎng)頁跳轉(zhuǎn)方式構(gòu)建關(guān)聯(lián),從而實現(xiàn)一個簡單的操作流程,流程說明如下:(1)當(dāng)用戶訪問:8000時,瀏覽器將呈現(xiàn)用戶注冊頁面,輸入新的用戶信息并單擊“確定”按鈕,視圖函數(shù)registerView將收到POST請求,將表單數(shù)據(jù)交由表單類MyUserCreationForm實現(xiàn)用戶注冊。(2)如果用戶注冊失敗,就提示錯誤信息并返回用戶注冊頁面;如果注冊成功,就由表單類MyUserCreationForm創(chuàng)建用戶,保存在模型MyUser的數(shù)據(jù)表中。默認情況下,新用戶不具備任何權(quán)限,因此視圖函數(shù)registerView為新用戶賦予自定義權(quán)限vip_myuser并跳轉(zhuǎn)到用戶登錄頁面。(3)在用戶登錄頁面輸入新用戶的賬號和密碼并單擊“確定”按鈕,視圖函數(shù)loginView將收到POST請求,從請求參數(shù)獲取用戶信息并進行驗證。如果用戶驗證失敗,就提示錯誤信息并返回用戶登錄頁面;如果用戶驗證成功,就執(zhí)行用戶登錄并跳轉(zhuǎn)到用戶中心頁面。(4)用戶中心頁面設(shè)有裝飾器permission_required,用于檢測用戶是否具有vip_myuser權(quán)限。如果用戶權(quán)限檢測失敗,就跳轉(zhuǎn)到用戶登錄頁面;如果檢測成功,就說明當(dāng)前用戶具有vip_myuser權(quán)限,能正常訪問用戶中心頁面。視圖函數(shù)infoView使用了裝飾器login_required和permission_required,分別對當(dāng)前用戶的登錄狀態(tài)和用戶權(quán)限進行校驗,兩者的說明如下:(1)login_required用于設(shè)置用戶登錄訪問權(quán)限。如果當(dāng)前用戶在尚未登錄的狀態(tài)下訪問用戶中心頁面,程序就會自動跳轉(zhuǎn)到指定的路由地址,只有用戶完成登錄后才能正常訪問用戶中心頁。login_required的參數(shù)有function、redirect_field_name和login_url,參數(shù)說明如下:●參數(shù)function:默認值為None,這是定義裝飾器的執(zhí)行函數(shù)?!駞?shù)redirect_field_name:默認值是next。當(dāng)?shù)卿洺晒χ?,程序會自動跳回之前瀏覽的網(wǎng)頁。●參數(shù)login_url:設(shè)置用戶登錄的路由地址。默認值是settings.py的配置屬性LOGIN_URL,而配置屬性LOGIN_URL需要開發(fā)者自行在settings.py中配置。(2)permission_required用于驗證當(dāng)前用戶是否擁有相應(yīng)的權(quán)限。若用戶不具備權(quán)限,則程序?qū)⑻D(zhuǎn)到指定的路由地址或者拋出異常。permission_required的參數(shù)有perm、login_url和raise_exception,參數(shù)說明如下:●參數(shù)perm:必選參數(shù),判斷當(dāng)前用戶是否具備某個權(quán)限。參數(shù)值為固定格式,如user.vip_myuser,user為項目應(yīng)用名稱,vip_myuser是數(shù)據(jù)表auth_permission的字段codename?!駞?shù)login_url:設(shè)置驗證失敗所跳轉(zhuǎn)的路由地址,默認值為None。若不設(shè)置參數(shù),則驗證失敗后會拋出404異常?!駞?shù)raise_exception:設(shè)置拋出異常,默認值為False。裝飾器permission_required的作用與內(nèi)置函數(shù)has_perm相同,視圖函數(shù)infoView也可以使用函數(shù)has_perm實現(xiàn)裝飾器permission_required的功能,代碼如下:最后在模板文件user.html和info.html中編寫網(wǎng)頁代碼,模板文件user.html主要生成用戶注冊和登錄頁面;模板文件info.html生成用戶中心頁面,兩者的代碼如下:模板文件user.html設(shè)置模板上下userLogin、tips和user,每個上下文的作用說明如下:●userLogin判斷當(dāng)前頁面的功能類型,從而顯示相應(yīng)的網(wǎng)頁內(nèi)容,若userLogin的值為False,則當(dāng)前頁面為用戶注冊頁面,否則為用戶登錄頁面。●tips是顯示的提示信息,比如用戶注冊失敗或用戶不存在等異常信息?!駏ser是表單類MyUserCreationForm的實例化對象,由user生成網(wǎng)頁表單,從而實現(xiàn)用戶注冊和登錄功能。模板文件info.html使用模板上下文user和perms,但視圖函數(shù)infoView沒有定義變量user和perms。模板上下文user和perms是在Django解析模板文件的過程中生成的,它們與配置文件settings.py的TEMPLATES設(shè)置有關(guān)。我們查看settings.py的TEMPLATES配置信息,代碼如下:因為TEMPLATES定義了處理器集合context_processors,所以在解析模板文件之前,Django依次運行處理器集合的程序。當(dāng)運行到處理器auth時,程序會生成變量user和perms,并且將變量傳入模板上下文TemplateContext中,因此模板中可以直接使用模板上下文user和perms。運行MyDjango項目,在瀏覽器上訪問:8000進入用戶注冊頁面,創(chuàng)建新用戶root,密碼為mydjango123,然后在用戶登錄頁面使用新用戶root完成登錄過程,最后在用戶中心頁面查看相關(guān)的用戶信息,如圖10-23所示。圖10-23用戶中心頁面如果在Admin后臺系統(tǒng)創(chuàng)建普通用戶user1,并且該用戶不賦予任何權(quán)限,在用戶登錄頁面使用user1完成登錄過程,Django就會重新跳轉(zhuǎn)到用戶登錄頁面,并且在登錄頁面的路由地址設(shè)置請求參數(shù)next,這說明當(dāng)前用戶不具備自定義權(quán)限vip_myuser,導(dǎo)致無法訪問用戶中心頁面,如圖10-24所示。圖10-24用戶登錄頁面10.7用戶組的設(shè)置與使用用戶組是對用戶進行分組管理,其作用是在權(quán)限控制中可以批量地對用戶權(quán)限進行分配,無需將權(quán)限一個一個地分配到每個用戶,節(jié)省維護的工作量。將用戶加入某個用戶組,該用戶就擁有該用戶組所具備的權(quán)限。例如用戶組teachers擁有權(quán)限can_add_lesson,那么所有屬于teachers用戶組的用戶都具備can_add_lesson權(quán)限。我們知道用戶、權(quán)限和用戶組三者之間是多對多的數(shù)據(jù)關(guān)系,而用戶組可以理解為用戶和權(quán)限之間的中轉(zhuǎn)站。設(shè)置用戶組分為兩個步驟:設(shè)置用戶組的權(quán)限和設(shè)置用戶組的用戶。設(shè)置用戶組的權(quán)限主要對數(shù)據(jù)表auth_group和auth_permission構(gòu)建多對多的數(shù)據(jù)關(guān)系,數(shù)據(jù)關(guān)系保存在數(shù)據(jù)表auth_group_permissions中。以10.6節(jié)的MyDjango項目為例,其數(shù)據(jù)庫結(jié)構(gòu)如圖10-25所示。圖10-25MyDjango的數(shù)據(jù)表在數(shù)據(jù)表auth_group中新建一行數(shù)據(jù),表字段name為“用戶管理”,當(dāng)前數(shù)據(jù)在項目中代表一個用戶組;此外,還可以在Admin后臺系統(tǒng)創(chuàng)建用戶組,但新建的用戶組無須添加任何權(quán)限,如圖10-26所示。圖10-26在Admin后臺系統(tǒng)創(chuàng)建用戶組下一步對用戶組“用戶管理”進行權(quán)限分配,在PyCharm的Terminal中使用Django的Shell模式實現(xiàn)用戶組的權(quán)限配置,代碼如下:#用戶組的權(quán)限配置
#導(dǎo)入內(nèi)置模型Group和Permission
>>>fromdjango.contrib.auth.modelsimportGroup
>>>fromdjango.contrib.auth.modelsimportPermission
#獲取某個權(quán)限對象p
>>>p=Permission.objects.get(codename='vip_myuser')
#獲取某個用戶組對象group
>>>group=Group.objects.get(id=1)
#將權(quán)限對象p添加到用戶組group中
>>>group.permissions.add(p)
上述代碼將自定義權(quán)限vip_myuser添加到用戶組“用戶管理”,功能實現(xiàn)過程如下:(1)從數(shù)據(jù)表auth_permission中查詢自定義權(quán)限vip_myuser的對象p,對象p是數(shù)據(jù)表字段codename等于vip_myuser的數(shù)據(jù)信息。(2)從數(shù)據(jù)表auth_group中查詢用戶組“用戶管理”的對象group,對象group是數(shù)據(jù)表主鍵等于1的數(shù)據(jù)信息。(3)由對象group使用permissions.add方法將權(quán)限對象p和用戶組對象group綁定,在數(shù)據(jù)表auth_group_permission中構(gòu)建多對多的數(shù)據(jù)關(guān)系,數(shù)據(jù)表的數(shù)據(jù)信息如圖10-27所示。圖10-27數(shù)據(jù)表auth_group_permissions除了添加用戶組的權(quán)限之外,還可以刪除用戶組已有的權(quán)限,代碼如下:#刪除當(dāng)前用戶組group的vip_myuser權(quán)限
>>>group.permissions.remove(p)
#刪除當(dāng)前用戶組group的全部權(quán)限
>>>group.permissions.clear()
最后實現(xiàn)用戶組的用戶分配,這個過程是對數(shù)據(jù)表auth_group和user_myuser構(gòu)建多對多的數(shù)據(jù)關(guān)系,數(shù)據(jù)關(guān)系保存在數(shù)據(jù)表user_myuser_groups中。在Django的Shell模式下實現(xiàn)用戶組的用戶分配,代碼如下:#將用戶分配到用戶組
#導(dǎo)入模型Group和MyUser
>>>fromuser.modelsimportMyUser
>>>fromdjango.contrib.auth.modelsimportGroup
#獲取用戶對象user,代表用戶名為user1的數(shù)據(jù)信息
>>>user=MyUser.objects.get(username='user1')
#獲取用戶組對象group,代表用戶組“用戶管理”的數(shù)據(jù)信息
>>>group=Group.objects.get(id=1)
#將用戶添加到用戶組
>>>user.groups.add(group)
上述代碼將用戶user1添加到用戶組“用戶管理”,實現(xiàn)過程與用戶組的權(quán)限設(shè)置有相似之處,只是兩者使用的模型和方法有所不同。查看數(shù)據(jù)表user_myuser_groups,數(shù)據(jù)信息如圖10-28所示。圖10-28數(shù)據(jù)表user_myuser_groups除了添加用戶組的用戶之外,還可以刪除用戶組已有的用戶,代碼如下:#刪除用戶組某一用戶
>>>user.groups.remove(group)
#清空用戶組全部用戶
>>>user.groups.clear()
第11章常用的Web應(yīng)用程序Django為開發(fā)者提供了常見的Web應(yīng)用程序,如會話控制、緩存機制、CSRF防護、消息框架、分頁功能、國際化和本地化、單元測試和自定義中間件。內(nèi)置的Web應(yīng)用程序大大優(yōu)化了網(wǎng)站性能,并且完善了安全防護機制,同時也提高了開發(fā)者的開發(fā)效率。11.1會話控制Django內(nèi)置的會話控制簡稱為Session,可以為用戶提供基礎(chǔ)的數(shù)據(jù)存儲。數(shù)據(jù)主要存儲在服務(wù)器上,并且網(wǎng)站的任意站點都能使用會話數(shù)據(jù)。當(dāng)用戶第一次訪問網(wǎng)站時,網(wǎng)站的服務(wù)器將自動創(chuàng)建一個Session對象,該Session對象相當(dāng)于該用戶在網(wǎng)站的一個身份憑證,而且Session能存儲該用戶的數(shù)據(jù)信息。當(dāng)用戶在網(wǎng)站的頁面之間跳轉(zhuǎn)時,存儲在Session對象中的數(shù)據(jù)不會丟失,只有Session過期或被清理時,服務(wù)器才將Session中存儲的數(shù)據(jù)清空并終止該Session。11.1.1會話的配置與操作在4.2.3小節(jié)已講述過Session和Cookie的關(guān)系,本節(jié)將簡單回顧兩者的關(guān)系,說明如下:●Session存儲在服務(wù)器端,Cookie存儲在客戶端,所以Session的安全性比Cookie高?!癞?dāng)獲取某用戶的Session數(shù)據(jù)時,首先從用戶傳遞的Cookie里獲取sessionid,然后根據(jù)sessionid在網(wǎng)站服務(wù)器找到相應(yīng)的Session?!馭ession存放在服務(wù)器的內(nèi)存中,Session的數(shù)據(jù)不斷增加會造成服務(wù)器的負擔(dān),因此存放在Session中的數(shù)據(jù)不能過于龐大。在創(chuàng)建Django項目時,Django已默認啟用Session功能,每個用戶的Session通過Django的中間件MIDDLEWARE接收和調(diào)度處理,可以在配置文件settings.py中找到相關(guān)信息,如圖11-1所示。圖11-1Session功能配置當(dāng)訪問網(wǎng)站時,所有的HTTP請求都經(jīng)過中間件處理,而中間件SessionMiddleware會判斷當(dāng)前請求的用戶身份是否存在,并根據(jù)判斷結(jié)果執(zhí)行相應(yīng)的程序處理。中間件SessionMiddleware相當(dāng)于HTTP請求接收器,根據(jù)請求信息做出相應(yīng)的調(diào)度,而程序的執(zhí)行則由settings.py的配置屬性INSTALLED_APPS的django.contrib.sessions完成,其配置信息如圖11-2所示。圖11-2Session的處理程序django.contrib.sessions實現(xiàn)了Session的創(chuàng)建和操作處理,如創(chuàng)建或存儲用戶的Session對象、管理Session的生命周期等。它默認使用數(shù)據(jù)庫存儲Session信息,執(zhí)行數(shù)據(jù)遷移時,在數(shù)據(jù)庫中可以看到數(shù)據(jù)表django_session,如圖11-3所示。圖11-3數(shù)據(jù)表django_session以10.6節(jié)的MyDjango項目為例,我們將通過例子來講述Session運行機制。首先清除瀏覽器的歷史記錄,確保以游客身份訪問MyDjango,即用戶在未登錄狀態(tài)下訪問Django。在瀏覽器打開開發(fā)者工具并訪問:8000,從開發(fā)者工具的Network標(biāo)簽的All選項里找到:8000的請求信息,若當(dāng)前Cookie沒有生成sessionid,則說明一般情況下,Django不會為游客身份創(chuàng)建Session,如圖11-4所示。圖11-4Cookie信息訪問用戶登錄頁面(:8000/login.html)并完成用戶登錄,打開用戶中心頁面的請求信息,可以看到Cookie生成帶有sessionid的數(shù)據(jù),并且數(shù)據(jù)表dja
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東梅州職業(yè)技術(shù)學(xué)院《交通規(guī)劃課程設(shè)計》2023-2024學(xué)年第二學(xué)期期末試卷
- 哈爾濱商業(yè)大學(xué)《物理化學(xué)實驗(上)》2023-2024學(xué)年第二學(xué)期期末試卷
- 黑龍江藝術(shù)職業(yè)學(xué)院《地理專業(yè)》2023-2024學(xué)年第二學(xué)期期末試卷
- 14保護呼吸器官(教學(xué)設(shè)計)-2024-2025學(xué)年科學(xué)三年級上冊人教鄂教版
- 河南輕工職業(yè)學(xué)院《嵌入式綜合實訓(xùn)》2023-2024學(xué)年第二學(xué)期期末試卷
- 中南林業(yè)科技大學(xué)《生命科學(xué)進展》2023-2024學(xué)年第二學(xué)期期末試卷
- 宜賓學(xué)院《天然產(chǎn)物》2023-2024學(xué)年第二學(xué)期期末試卷
- 哈爾濱商業(yè)大學(xué)《流體力學(xué)B》2023-2024學(xué)年第二學(xué)期期末試卷
- 瀘州四川瀘州瀘縣氣象局見習(xí)基地招收見習(xí)人員2人筆試歷年參考題庫附帶答案詳解
- 大連軟件職業(yè)學(xué)院《數(shù)據(jù)結(jié)構(gòu)實驗》2023-2024學(xué)年第二學(xué)期期末試卷
- 異位妊娠護理查房版本
- 人教版 八年級數(shù)學(xué)下冊 第19章 單元綜合測試卷(2025年春)
- 2024年美發(fā)師(高級技師)職業(yè)鑒定考試題庫(含答案)
- 2025年山東藥品食品職業(yè)學(xué)院高職單招職業(yè)技能測試近5年常考版參考題庫含答案解析
- 2024年05月湖南招商銀行長沙分行長期社會招考筆試歷年參考題庫附帶答案詳解
- 滬科版(2024新版)數(shù)學(xué)七年級下冊第6章 實數(shù) 單元測試卷(含答案)
- 2025新人教版英語七年級下單詞英譯漢默寫表(小學(xué)部分)
- 電子物料基礎(chǔ)知識
- 外科疝氣的個案護理
- 2025屆江蘇省南京市鹽城市高三一??荚囌Z文試題 課件
- 幼兒園保育教育質(zhì)量自評指導(dǎo)手冊(試行)
評論
0/150
提交評論