大家好,這是皮爺給大家帶來的最新的學習Python能幹啥?之Django教程,從零開始,到最後成功部署上線的項目。這一節,我們將寫404頁面。
Peekpa.com的官方地址:http://peekpa.com
皮爺的每一篇文章,都配置相對應的代碼。這篇文章的代碼Tag是Post_023
前幾節,我們就針對網站的功能,進行了開發,其實基本功能已經完成的差不多了,這一節,我們就要針對網站的權限進行一下管理。
權限管理分析
爲什麼需要權限管理?
原因就是我們在第11講的時候,開發了Login功能,當時我們創建了管理員賬號,並且隨後的章節,我們開發了後臺管理系統。
雖然我們有管理員賬號,也有登錄功能,但是細心的同學,就會發現,我們之前開發的CMS系統,其實不用登錄也能使用的。
這就是Bug啊,這就是問題啊,如果上線正式環境了,你的系統豈不是隨隨便便就讓別人登錄後臺了,而且還能管理你的文章?
那麼今天,我們就要給CMS系統,加上權限,使得用戶必須登錄了才能使用CMS系統,如果沒有登錄,是不能使用的。
原理詳解
如果一個頁面,沒有登錄,那麼就不能訪問。可以實現這樣功能的東西,應該就只有request了。
各位不知道注意沒有,每一次我們在寫視圖函數的時候,不管是post方法還是get方法,或者是其他方法,都要傳入一個request參數,而且是必傳的。其實,這裏的request,就是WSGIRequest類:
他是繼承自django.http.HttpRequest
類,這個類的官方文檔:
https://docs.djangoproject.com/en/3.0/ref/request-response/
針對我們,如果要實現用戶登錄之後才能訪問,那麼我們就可以看到,HttpRequest裏面有一個變量,叫user
。我們就可以拿這個變量來做判斷。
核心的代碼,其實就是下面這段:
if request.user.is_authenticated:
... # Do something for logged-in users.
else:
... # Do something for anonymous users.
我們要通過修飾器的方式來實現權限管理。什麼是修飾器?就是在一個方法前面,通過@xxx
來寫的修飾器。用來修飾整個方法。
登出方法
我們之前的Login頁面有登錄方法,我們還需要寫一個登出方法,並且放到CMS頂部的Navbar上面。
def logout_view(request):
logout(request)
return redirect(reverse('cms:login'))
權限實戰
我們既然是要權限管理,我們就應該在PeekpaUser應用下,創建decorators.py
文件,然後在裏面寫裝飾器。
def peekpa_login_required(func):
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated:
return func(request, *args, **kwargs)
else:
if request.is_ajax():
return restful.unauth(message='請先登錄!')
else:
return redirect(reverse('cms:login'))
return wrapper
那麼我們把這個裝飾器導入到CMS中,添加在cms_dashboard
和category_manage_view
試一下:
@peekpa_login_required
def cms_dashboard(request):
@peekpa_login_required
def category_manage_view(request):
這個時候,我們在瀏覽器裏面輸入Dashboard的網址http://localhost:8000/cms/dashboard/
,會看到頁面直接跳轉到了登錄頁面:
我們可以看到,右下角的network裏面,我們的http://localhost:8000/cms/dashboard/
返回結果是302,所以頁面自動跳轉到了登錄頁面。
同樣,我們來看一下category manage
的頁面,地址是http://localhost:8000/cms/dashboard/category/manage
:
右下角顯示的是一樣的。302返回結果,自動跳轉到了login頁面。
但是這個時候,我們去看一下category publish
頁面,因爲這個頁面我們沒有添加裝飾器,地址是http://localhost:8000/cms/dashboard/category/publish
:
可以看到,直接就進來了,而且功能都和之前開發時候一模一樣。說明修飾器還是管用的。
接下來,我們再次回到category manage
的頁面,去登錄一下,然後看看還能不能進入這個頁面:
發現登錄之後就完全沒有問題了。所以,我們想要給cms加上權限驗證,就只需要在視圖函數之前添加@peekpa_login_required
修飾器就可以了。
這個時候,心細的同學可能就會發現,我們這裏所有的修飾器修飾的,其實都是方法。實際在我們的系統裏,還有一些視圖函數映射的其實是視圖類,比如:
http://localhost:8000/cms/dashboard/exchangelink/edit?exchangelink_id=1
這個地址,它背後映射的就是ExchangeLinkEditView。
我們在沒有做任何修改的時候,打開這個地址,可以很成功的就跳轉到了ExchangeLink的修改頁面:
所以,我們針對視圖類,還沒有做任何保護。所以,我們這裏得使用@method_decorator
修飾器,具體做法如下:
@method_decorator(peekpa_login_required, name='get')
class ExchangeLinkEditView(View):
def get(self, request):
exchangelink_id = request.GET.get('exchangelink_id')
exchangeLink = ExchangeLink.objects.get(pk=exchangelink_id)
context = {
'item_data': exchangeLink,
'list_data_status': ExchangeLink.STATUS_ITEMS,
}
return render(request, 'cms/exchangelink/publish.html', context=context)
第一個變量是方法裝飾器,第二個name則是說的需要修飾的方法。我們這裏只修飾GET方法。如果要修飾post,這裏就寫name=post;如果要修飾get和post方法,這裏就直接寫name=dispatch。
這個時候,我們再去訪問一下http://localhost:8000/cms/dashboard/exchangelink/edit?exchangelink_id=1
:
就會發現,頁面被自動跳轉到了login頁面。右下角也是看到了302請求。
404頁面
404頁面,相信大家都很熟悉,當我們啓動服務,我們再打開一個我們沒有過url的頁面,比如http://127.0.0.1:8000/mm
,那麼頁面就會出現下面的樣子:
當你看到這個頁面,說明這麼幾點問題:
- 你的settings.py文件裏的DEBUG變量值是True
- 你沒有寫404頁面,所以看到的是系統的debug錯誤頁面。
如果我們想要看到實際的404頁面,則需要在settings.py裏面,修改DEBUG
和ALLOWED_HOSTS
的值爲一下:
DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1']
他們分別表示,當前網站不是debug模式,允許訪問的host地址是127.0.0.1
那麼這個時候,我們再次訪問http://127.0.0.1:8000/mm
,就會看到這樣:
這個白色的頁面,其實就是系統自帶的404頁面。
我們要做的,就是定製我們自己的頁面,只需要在template目錄下,創建一個叫404.html的頁面就可以:
這個時候,我們需要重啓一下服務器,然後再次訪問那個不存在的頁面,就會看到:
怎麼樣?是不是我們的頁面得到了定製?Django是不是很強大, 很簡單的方式就定製了錯誤處理網頁。
技術總結
最後總結一下,
訪問權限和404:
- 如果要實現用戶訪問的限制,那麼就通過HttpRequest.user來做判斷;
- 一般來說,都是通過修飾器的方式來處理的;
- 方法修飾器,直接添加
@xxx
在方法前,類修飾器,則使用@method_decorator(peekpa_login_required, name='get')
; - 404頁面則是需要在template模板下,直接創建一個叫做
404.html
的文件就可以了; - 如果想要看真是的404頁面長什麼樣子,那就必須得把settings.py文件裏面的
DEBUG=True
,同時還要設置ALLOWED_HOSTS
的值; - 完畢。
獲取代碼的唯一途徑:關注『皮爺擼碼』,回覆『代碼』即可獲得。
長按下圖二維碼關注,如文章對你有啓發,歡迎在看與轉發。