繼 Day20 ,透過path的設定,我們現在有了更多的網頁
但是在實作上,可能會因為找不到該網站而發生錯誤,因此我們在撰寫程式的同時,也要考量到發生例外的狀況,因此 Day20 的程式碼還需要改良
而當我們在瀏覽網頁的同時,若是該網頁不存在,就會發生 HTTP 404
對於這方面的處理,Django提供了一個方便的方法,能夠讓我們處理發生 HTTP 404 的問題
因此 Day20 的 singleVendor
函式 要修改成如下
# 額外 import Http404
from django.http import Http404
def singleVendor(request, id):
try:
vendor_list = Vendor.objects.get(id=id)
except Vendor.DoesNotExist:
raise Http404
context = {
'vendor_list': vendor_list
}
return render(request, 'vendors/vendor_detail.html', context)
如此一來就能夠正常的顯示HTTP 404
不過這跟實際上看到的 404 還是不一樣,因為 Django 目前還處在 Debug 的模式,也就是說你能夠在 settings.py 看到這個設定
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
因此我們要去修改 Debug 模式
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
不過同時,你也要將允許的網域加在 settings.py 的 ALLOWED_HOSTS,這裡因為只要測試功能,所以我們可以改成這樣,所以實際上的設定值就要取決於你的網站而做設定囉!
ALLOWED_HOSTS = ['*']
接著再來看網頁的話,你就可以看到正常的 HTTP 404 頁面
因此當網頁要上線的時候,務必要將 Debug模式 關掉呀!!
ALLOWED_HOSTS = ['*']是個壞榜樣 好孩子不要亂學
但是我們也一直強調了,Django 的中心思想就是 DRY (Don't Repeat Yourself),因此 Django 另外還提供了一個更方便的方法 get_object_or_404
從字面上,我們就可以知道它的意思就是
也就是說,你能夠將程式碼修改成這樣
from django.shortcuts import get_object_or_404 # 新增
def singleVendor(request, id):
vendor_list = get_object_or_404(Vendor, id=id)
# try:
# vendor_list = Vendor.objects.get(id=id)
# except Vendor.DoesNotExist:
# raise Http404
context = {
'vendor_list': vendor_list
}
return render(request, 'vendors/vendor_detail.html', context)
如此一來 Django 就幫你完成了例外處理的工作,勢必幫你在開發上省掉很多這種例外的時間呢! ^^
當然你有時間,也別忘了去看看 get_object_or_404 的原始碼 ( 增廣見聞
def get_object_or_404(klass, *args, **kwargs):
"""
Use get() to return an object, or raise a Http404 exception if the object
does not exist.
klass may be a Model, Manager, or QuerySet object. All other passed
arguments and keyword arguments are used in the get() query.
Like with QuerySet.get(), MultipleObjectsReturned is raised if more than
one object is found.
"""
queryset = _get_queryset(klass)
if not hasattr(queryset, 'get'):
klass__name = klass.__name__ if isinstance(klass, type) else klass.__class__.__name__
raise ValueError(
"First argument to get_object_or_404() must be a Model, Manager, "
"or QuerySet, not '%s'." % klass__name
)
try:
return queryset.get(*args, **kwargs)
except queryset.model.DoesNotExist:
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
若是你今天要處理的並不只是一個物件, Django 也有幫你準備 get_list_or_404
而你可以很容易就理解兩者之間的差異
get
取得一個物件filter
取得一些物件今天帶大家了解,Django 如何在撰寫網頁時,更方便地處理這一些例外,而在使用這些好用的函式時,有空去追個 code也是一件相當有趣的事情^^
今天介紹到這邊,我們明天見
祈福 台鐵乘客 及 救難國軍 平安