使用类视图:更少的代码更好
以上提到的,detail()
和results()
视图是非常简单的,index()
,展示了一系列投票,也是类似的。
这些视图代表了一种常见的基本web开发:通过URL中传递的参数来从数据库中获取数据,加载一个模版,然后返回渲染好的模版。因为这非常常见,所以Django提供了一个捷径,叫做"类视图"
系统。
类视图抽取常见的模式来达到你甚至不需要写python代码就能写一个app的效果。
让我们来将我们的投票应用转换为类视图系统,所以我们可以删除一些我们自己的代码。我们只需完成几个步骤来达到那个目的:
- 转换
URLconf
- 删除一些老的、不需要的视图
- 引入建立在Django类视图上一些新的视图
修改URLconf
首先,打开polls/urls.py
的URLconf
,改变成这样:
from django.conf.urls import url
from . import views
urlpatterns=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^(?P<pk>[0-9]+)/$',views.DetailView.as_view(),name='detail'),
url(r'^(?P<question_id>[0-9]+)/results/$',views.ResultView.as_view(),name='results'),
url(r'^(?P<pk>[0-9]+)/vote/$',views.vote,name='vote'),
]
修改视图
下面,我们打算移除我们之前写的index
、detail
和results
视图,而是使用Django的类视图。打开polls/views.py
from django.shortcuts import render,get_object_or_404
from django.http import HttpResponse,HttpResponseRedirect,Http404
from django.template import RequestContext,loader
from .models import Question,Choice
from django.core.urlresolvers import reverse
from django.views import generic
# Create your views here.
class IndexView(generic.ListView):
template_name='polls/index.html'
context_object_name='latest_question_list'
def get_queryset(Self):
return Question.objects.order_by('-pub_date')[:5]
class DetailView(generic.DetailView):
model=Question
template_name='polls/detail.html'
class ResultView(generic.DetailView):
model=Question
template_name='polls/results.html'
这里,我们使用两个类视图:ListView
和DetailView
,这两个视图分别是从"展示一系列物体"
和"展示一个特定类型物体的详情页"
。
- 每个类视图需要知道它关联哪个模型,这可以通过
model
属性来提供 DetailView
类视图希望从URL中捕获的主键值叫做pk
,所以我们将question_id
改变为pk
。
默认,DetailView
类视图使用一个模版,叫做<app name>/<model name>_detail.name
,在我们这个例子中,它将使用polls/question_detail.html
这个模版。template_name
这个属性被用来告诉Django要使用一个特定的模版,而不是自动产生一个默认的模版名。我们也为results
列表视图声明template_name
,这确保results
视图和detail
视图有不同的外观,尽管都是一个DetailView
。