避免无聊的视图和URL。
项目描述
问题
在查看 Ruby on Rails 时,我发现Django缺少一个很好的功能: 控制器。与我所读的相反,Django中的视图并不真正等同于Rails中的控制器。Rails控制器基本上是 一组Django视图和Django URL模式。除了驱除无聊的URL工作外,这是一种将属于同一模型的视图分组的好方法。
任何好的Django用户都会与通用视图建立联系 - 尤其是带有 类 的通用视图。这是避免重复相同代码(只需进行一些更改)的简单解决方案。但这并没有简化URL模式,我们经常需要定义这样的文件
# views.py
from django.views.generic import ListView, DetailView  # and so on…
from .models import Example
class ExampleListView(ListView):
    model = Example
class ExampleDetailView(DetailView):
    model = Example
# and so on…
# urls.py
from django.conf.urls import patterns, url
from .views import *
urlpatterns = patterns('',
    url('^examples/$', ExampleListView.as_view(), name='example_index'),
    url('^examples/(?P<pk>\d+)$', ExampleDetailView.as_view(),
        name='example_detail'),
    # and so on…
)
对于单个模型来说,这看起来很简单。对于包含数十个模型的复杂应用程序来说,这看起来很痛苦 - 肯定不是DRY [1]。
解决方案
django-viewsets 提出了一个受Rails控制器启发的解决方案。 ViewSet 是一个类,它从一个基于类的通用视图集合中构建一组URL模式。它设计为可覆盖,因此它适用于标准用法以及高级用法。
安装
[sudo] pip install django-viewsets
您无需更改项目的 settings.py 文件。
用法
ModelViewSet
提供的视图和URL
| 通用视图 | URL | URL名称 | 
| ListView | your-models/ | your-model_index | 
| DetailView | your-models/[pk] | your-model_detail | 
| 创建视图 | your-models/create/ | your-model_create | 
| 更新视图 | your-models/[pk]/update | your-model_update | 
| 删除视图 | your-models/[pk]/delete | your-model_delete | 
基本用法
在您的应用程序(或项目)的 urls.py 中
from django.conf.urls import patterns, url, include
from viewsets import ModelViewSet
from .models import YourModel
urlpatterns = patterns('',
    url('', include(ModelViewSet(YourModel).urls)),
)
您还可以提供其他 基本属性 作为关键字参数。例如,如果您想使用slug而不是主键作为URL模式的键,则第2行和第6行变为
from viewsets import ModelViewSet, SLUG  # line 2
url('', include(ModelViewSet(YourModel, id_pattern=SLUG).urls)),  # line 6
高级用法
这允许更多的定制。
在您的应用程序 views.py 中
from viewsets import ModelViewSet
from .models import YourModel
class YourModelViewSet(ModelViewSet):
    model = YourModel
在您的应用程序(或项目)的 urls.py 中
from django.conf.urls import patterns, url, include
from .views import YourModelViewSet
urlpatterns = patterns('',
    url('', include(YourModelViewSet().urls)),
)
这个用法有趣的是,您可以轻松地自定义视图和URL。假设您想在更新和删除URL模式中使用主键,但想在详细视图中使用slug。最快的方法是
from viewsets import ModelViewSet, SLUG
class CustomModelViewSet(ModelViewSet):
    def __init__(self, *args, **kwargs):
        self.views['detail_view']['pattern'] = SLUG
        super(CustomModelViewSet, self).__init__(*args, **kwargs)
在这里我们不设置 model 属性,这样 CustomModelViewSet 就可以用于您的任何模型。当然,您现在可以使用 CustomModelViewSet,无论是基本用法还是高级用法。而且,如果这个视图集只打算与特定模型一起使用,我们也可以设置 model。
基本属性
- model
- ModelViewSet将从中创建视图和URL的模型类。这是唯一的必填属性。 
- base_url_pattern
- 覆盖所有URL模式中的 your-models。如果未设置,则从 model._meta.verbose_name_plural 计算得出。 
- base_url_name
- 覆盖所有URL名称中的 your-model。如果未设置,则从 model._meta.verbose_name 计算得出。 
- id_pattern
- 覆盖所有URL模式中的 [pk]。您可以使用 viewsets.PK 或 viewsets.SLUG。 
- excluded_views
- 来自 views 的键的序列。默认未设置。例如:('create_view', 'delete_view',)。 
- namespace
- 如果您的应用程序有URL命名空间,请设置此选项。它用于在删除视图中重定向到 main_view。您还可以设置 main_url。 
- main_view
- 用于计算 main_url。默认为 'list_view'。 
- main_url
- 删除视图重定向的主要URL。如果设置,则忽略 main_view。 
高级属性
- views
- 定义视图和URL的字典。默认为 CRUD [2]。