用简单的语言解释什么是Django通用视图?
这篇页面的前两段说了通用视图的目的,就是为了让我的生活更轻松,不那么单调,还能让我更吸引女性(最后一句是我自己编的):
https://docs.djangoproject.com/en/1.4/topics/generic-views/
我当然希望生活能更好,但通用视图到底是干嘛的呢?感觉有很多专业术语在这里被提到,反而让人更困惑,而不是解释清楚。
通用视图是不是和Ruby on Rails里的脚手架类似?介绍的最后一点似乎在暗示这个。这样说准确吗?
3 个回答
关于你的第二个问题:不,通用视图和RoR中的脚手架没有关系。脚手架顾名思义,就像是代码生成一样。而通用视图是另外一回事。
我使用通用视图的主要目的是替代非常基础的 render_to_response
函数。这是你可以用 render_to_response
写一个简单视图的方式:
def my_view(request):
return render_to_response('my_template.html')
但这真的很基础!比如说,模板无法访问请求的上下文,除非你明确地传递它。
所以我更喜欢使用通用视图:
def my_view(request):
return direct_to_template(request, template='my_template.html')
现在请求的上下文会被传递过来了!这只是个开始。通用视图在你想要显示列表或详细视图时特别有用。它们会处理查询数据库和给用户发送消息等事情。
所以,通用视图是一些高级功能,帮助你从视图中创建响应。
通用视图让你写的代码变得更简洁。
对比一下:
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
from myapp.models import Context
def edit(request, item_id):
object = get_object_or_404(Context, pk=item_id)
if request.method == 'POST':
form = ContextForm(request.POST, instance=object)
if form.is_valid():
form.save()
return redirect('myapp-context-index')
else:
form = ContextForm(instance=object)
return render_to_response("myapp/context/edit.html", {'object': object, 'form': form})
和:
from django.core import urlresolvers
from django.views.generic.create_update import update_object
from myapp.models import Context
def edit(request, item_id):
return update_object(request,
object_id=item_id,
form_class=ContextForm,
template_name="myapp/context/edit.html",
post_save_redirect=urlresolvers.reverse("myapp-context-index")
)
就像你平常写的视图,它们其实都是普通的函数。如果你愿意,可以完全通过URL配置来设置这个视图,不过我觉得上面的用法更清晰一些。
作为额外的好处,你还可以得到:
- 登录认证检查(只需设置
login_required=True
) - 来自
django.contrib.messages
的成功状态消息。 - 检查错误的代码更少。
- 当你提供
model
参数而不是form_class
时,会自动生成一个默认的ModelForm
。
template_name
默认是 "appname/model_form.html",但我觉得这个有点多余。
这是它们共享的表单类:
class ContextForm(forms.ModelForm):
"""The form for a context"""
class Meta:
model = Context
exclude = ('collection',)
def save(self, commit=True):
"""Overwritten save to force collection_id to a value"""
model = super(ContextForm, self).save(commit=False)
model.collection_id = 1
if commit:
model.save()
return model
Django的通用视图其实就是一些普通的Python函数,它们可以处理在网页应用中非常常见的事情。
根据你正在开发的应用类型,这些通用视图可以帮你省去写很多简单的视图代码。
比如,direct_to_template
这个通用视图只需要渲染一个模板,并且使用RequestContext
(这意味着模板可以获取请求中的信息,比如当前用户等)。
举个简单的例子,你可以把原本需要写的代码:
# urls.py
url('^some-url/$', some_view)
# views.py
def some_view(request):
return render_to_response('template_name.html', context_instance=RequestContext(request))
简化成这样:
# urls.py
url('^some-url/$', direct_to_template, {'template': 'template_name.html'})
# views.py doesn't need any code for this view anymore
还有一些更复杂的通用视图,用于处理常见的操作,比如“显示模型列表”或者“向数据库添加模型”。
另外,因为通用视图就是函数,所以你可以在自己的视图函数中调用它们,这样可以完成“大部分工作”,当你需要的功能和通用情况稍有不同的时候,这样做会很方便。