您的位置:首页 > 编程语言 > Go语言

django框架从零开始_009_通用页面

2016-05-11 22:15 281 查看
参考:https://docs.djangoproject.com/en/1.9/intro/tutorial04/#use-generic-views-less-code-is-better

我们做的detail、result、index的界面非常简单,但是同时,也很冗余。这些页面做了标准网页开发应该做的事情:根据url从数据库中读取数据、加载模版页并显示出来。这种应用太常见了,所以django提供了一个快捷的"Generic Views"系统。它抽取出来的最简练的模式,你可以不用写什么view而就可以创建你的app。

下面让我们来把我们的polls系统利用generic views改写一下。我们需要做如下几步:

改写URLConf
删除不用的views
引入新的页面
首先修改polls/urls.py:
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]


和原来相比,我们引入了IndexView.as_view()内容,以及把<question_id>改成了<pk>。

下面我们去修改相对应的views。我们把我们老的index、detail、results页面用generic views替换。polls/views.py修改为:

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from .models import Question, Choice
from django.core.urlresolvers import reverse
from django.views import generic

class IndexView(generic.ListView):
template_name = 'polls/index.html'
context_object_name = 'latest_question_list'

def get_queryset(self):
''' return the last five published questions.'''
return Question.objects.order_by('-pub_date')[:5]

class DetailView(generic.DetailView):
model = Question
template_name = 'polls/detail.html'

class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'

def vote(request, question_id):
#return HttpResponse("You're voting on question %s." % question_id)
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {'question':question, 'error_message':'You did not select a choice'})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))


在这里,我们引入了两个generic views:ListViewDetailView。这两种view分别实现了“显示对象列表”以及“显示对象详细属性”的功能。

每一个generic view都需要知道它对应的对象类型是什么,用model属性赋值
DetailView需要知道对象的pk(从url传入),这也是我们把question_id改成pk的原因
DetailView默认会使用<app name>/<model name>_detail.html页面。如果需要手动设置,则修改template_name属性的值。例如我们分别制定了DetailView和ResultsView的模版名,使得他们虽然类型和model都相同,但是指向的页面不同。

类似的,ListView使用默认模版<app name>/<model name>_list.html,修改的时候同样改变template_name值。

在之前的步骤中,我们都给context变量赋值了我们需要传入的变量(question、latest_question_list之类)。在使用DetailView时,因为我们已经使用了django的model(Question),所以context名称会由django自动设置;而对于ListView,自动生成的context内容会是question_list,如果我们想修改他,那么就覆盖context_object_name属性值为我们想要的变量。当然,你也可以修改你的页面来适应django的默认值,但是显然指定context_object_name会更简单。

就是这些了,去你的server上尝试一下吧~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  django python