视图
总结一下:
- 进来的请求转入/hello/.
- Django通过在ROOT_URLCONF配置来决定根URLconf.
- Django在URLconf中的所有URL模式中,查找第一个匹配/hello/的条目。
- 如果找到匹配,将调用相应的视图函数
- 视图函数返回一个HttpResponse
- Django转换HttpResponse为一个适合的HTTP response, 以Web page显示出来
一个最简单的示例
from django.http import HttpResponse
def index(request):
return HttpResponse(Hello, world. You're at the polls index.)
每个视图都会响应以下两种情形中的其中一种:
- 返回一个包含请求页面内容的 HttpReponse 对象
- 引发类似于 Http404 的异常
改进的 views 示例
from django.http import HttpResponse
from django.template import RequestContext, loader
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = RequestContext(request, {
'latest_question_list': latest_question_list,
})
return HttpResponse(template.render(context))
但是,明显我们还自己多做了渲染模板的工作,为了将这份职责交给 django,我们再次进行改进:
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'polls/index.html', context)
render() 函数将 request 对象作为第一个参数,将模版名称作为第二个参数,并且将一个字典作为可选的第三个参数,他返回使用指定上下文和模板渲染出来的 HttpResponse 对象
引发一个404
from django.http import Http404
from django.shortcuts import render
from .models import Question
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404(Question does not exist)
return render(request, 'polls/detail.html', {'question': question})
这里引入了一个新概念,就是当没有查询的 Question 对象的时候,django 将会抛出一个 Http404 的异常。
但是,这个程序看上去又显得略微冗长,所以,django 又给我们提供了一个便利的写法:
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_object_or_404() 函数的第一个参数为
Django
模型,并且可以传入任意的关键字参数,这些参数都将传给模型管理器的 get() 函数。如果对象不存在,这个函数将会引发一个 Http404 异常。
小Tips
Why do we use a helper function get_object_or_404() instead of automatically catching the ObjectDoesNotExist exceptions at a higher level, or having the model API raise Http404 instead of ObjectDoesNotExist?
>
Because that would couple the model layer to the view layer. One of the foremost design goals of Django is to maintain loose coupling. Some controlled coupling is introduced in the django.shortcuts module.