Django的通用视图抽象出了一些在视图开发中常用的代码和模式,这样就可以在无需编写大量代码的情况下,快速编写出常用的数据视图。

Django内建通用视图实现如下功能:

  • 完成常用的简单任务:重定向到另外一个界面以及渲染一个指定的模板
  • 显示列表和某个特定对象的详细内容界面。
  • 呈现基于日期的数据的年/月/日归档界面,关联的详细页面,最新页面。

使用通用视图

from django.conf.urls.defaults import *
from django.views.generic.base import TemplateView

urlpatterns = patterns('',
    (r'^about/$', TemplateView.as_view(template_name='about.html'))
)

这个例子不需要代码的视图,直接从传递过来的额外参数获取信息并用于渲染视图

因为通用视图都是标准的视图函数,我们可以在我们自己的视图中重用它。 例如,我们扩展 about例子,把映射的URL从 /about//修改到一个静态渲染 about/.html 。 我们首先修改URL配置以指向新的视图函数:

from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
**from mysite.books.views import about_pages**

urlpatterns = patterns('',
    (r'^about/$', direct_to_template, {
        'template': 'about.html'
    }),
    **(r'^about/(\w+)/$', about_pages),**
)
from django.http import Http404
from django.template import TemplateDoesNotExist
from django.views.generic.simple import direct_to_template

def about_pages(request, page):
    try:
        return direct_to_template(request, template="about/%s.html" % page)
    except TemplateDoesNotExist:
        raise Http404()

-------------------------------------------------------------------------------------------------------------------------

对象的通用视图:

    direct_to_template非常有用,最有用的是呈现数据库中的数据,django内部有很多通用视图帮助我们很容易的生成对象的列表和明细视图。

让我们先看看其中的一个通用视图: 对象列表视图。 我们使用第五章中的 Publisher 来举例:

class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

    def __unicode__(self):
        return self.name

    class Meta:
        ordering = ['name']
要为所有的出版商创建一个列表页面,我们使用下面的URL配置:

from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher

publisher_info = {
    'queryset': Publisher.objects.all(),
}

urlpatterns = patterns('',
    (r'^publishers/$', list_detail.object_list, publisher_info)
)

   还需要一个模板,可以在额外参数字典里边包含一个template_name显示告诉object_list视图使用哪个模板:

from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher

publisher_info = {
    'queryset': Publisher.objects.all(),
    **'template_name': 'publisher_list_page.html',**
}

urlpatterns = patterns('',
    (r'^publishers/$', list_detail.object_list, publisher_info)
)

    这个模板将按照context中包含的变量object_list俩渲染,这个变量包含所有的书籍对象。

{% extends "base.html" %}

{% block content %}
    <h2>Publishers</h2>
    <ul>
        {% for publisher in object_list %}
            <li>{{ publisher.name }}</li>
        {% endfor %}
    </ul>
{% endblock %}

    这就是所要做的事情,要使用通用视图特性,只需要修改参数字典并传递给通用视图函数。

-------------------------------------------------------------------------------------------------------------------------

扩展通用视图:

    怎样使用通用视图来处理更多的情况,通用视图可以加快开发速度。几乎每种情况都有相应的方法来简易的扩展通用视图以处理这些情况,用到下边的方法:

    制作友好的模板Context:

    为了对编写模板的人表示友好,他们呢必须知道一些事情,更好的变量名应该是publisher_list而不是object_list,这样变量代表的内容就显而易见了。

from django.conf.urls.defaults import *
from django.views.generic import list_detail
from mysite.books.models import Publisher

publisher_info = {
    'queryset': Publisher.objects.all(),
    'template_name': 'publisher_list_page.html',
    'template_object_name': 'publisher',  <------------------可以修改,视图会通过在template_object_name后追加一个_list方式来创建列表项目的变量名字
}

urlpatterns = patterns('',
    (r'^publishers/$', list_detail.object_list, publisher_info)
)

    那么在模板文件 publisher_list_page.html 里,可以用(在template_object_name值的后面加_list,如) publisher_list 的写法,来代替 object_list。

    待续。