四、抛出404错误
如果访问的资源不存在的话,我们想抛出404错误,而不是暴露Django的错误信息。Django为我们提供了这样一个方法
-
get_object_or_404()
:将一个Django模型作为第一个位置参数,后面可以跟上任意个数的关键字参数,如果对象不存在则弹出Http404错误。 -
为什么我们使用辅助函数
get_object_or_404()
而不是自己捕获ObjectDoesNotExist
异常呢?还有,为什么模型API不直接抛出ObjectDoesNotExist
而是抛出Http404
呢?
因为这样做会增加模型层和视图层的耦合性。而Django
的设计思想中,最重要的思想之一就是要保证松散耦合。一些受控的耦合将会被包含在 django.shortcuts
模块中。
例子:当id不存在时,抛出404
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
-
还有一个
get_list_or_404()
方法
和get_object_or_404()
类似,只不过是用来替代filter()
函数,当查询列表为空时弹出404错误。(filter()
是模型API中用来过滤查询结果的函数,它的结果是一个列表集。而get则是查询一个结果的方法,和filter是一个和多个的区别) -
当然,因为自带的404等页面太丑,一般都是自定义404、500等页面;
1.urls.py
:
from django.contrib import admin
from django.urls import path
from app import views
urlpatterns = [
path('admin/', admin.site.urls),
]
# 增加的条目
handler400 = views.bad_request
handler403 = views.permission_denied
handler404 = views.page_not_found
handler500 = views.error
2.在应用/views.py文件增加对应的处理视图:
def bad_request(request):
return render(request, '400.html')
def permission_denied(request):
return render(request, '403.html')
def page_not_found(request):
return render(request, '404.html')
def error(request):
return render(request, '500.html')