Django基于类的通用视图 - 在单个Mixin中处理ListView和DetailView

时间:2013-01-17 00:02:06

标签: django django-class-based-views class-based-views

我有一个在线文档Django应用程序,它有一个基本URI:

/path/to/docs/<DOMAIN>/

这允许您查看该DOMAIN中的文档列表。它使用GCBV ListView。您可以使用以下命令请求DetailView DOCNAME:

/path/to/docs/<DOMAIN>/<SLUG>/

其中SLUG非常自我解释并且返回一条记录作为一个好的slug应该。这些子页面有自己的模板,分别为:

/path/to/docs/<DOMAIN>/<SLUG>/foo/
/path/to/docs/<DOMAIN>/<SLUG>/bar/
/path/to/docs/<DOMAIN>/<SLUG>/baz/

对于无版本文档,这很简单。但是,在另一个DOMAIN(我们称之为“联合”)中,执行可以使用不同版本的DOCNAME:

/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>/

/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>/foo/
/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>/bar/
/path/to/docs/<DOMAIN>/<SLUG>/<VERSION>//baz/

在这种情况下,如果用户请求:

/path/to/docs/<DOMAIN>/<SLUG>/

我不希望向用户显示DetailView - 我希望它们能够显示每个提供文档的VERSION的ListView:

Fantastic docs - Version 1 (/path/to/docs/federated/fantastic/1/)
Fantastic docs - Version 2 (/path/to/docs/federated/fantastic/2/)
Fantastic docs - Version 3 (/path/to/docs/federated/fantastic/3/)

我已经对GCBV进行了一些非常广泛的阅读,并且之前在不同的应用程序中对其中的许多进行了子类化,但我怀疑我无法在 urls.py 中单独输入以处理两者这些类型的查询(Detail和ListView)。实际上,Django向warns提供了关于混合GCBV的文档,特别是w.r.t. get_context_data()。

可以在我的Mixin内部执行的操作是查看DOMAIN名称,并在此基础上将请求分叉到ListView(对于版本化文档)或DetailView(对于非版本化的文档)。我搜遍了Django文档,但没有看到任何这方面的例子。任何人都可以帮助我吗?

注意: 我想到了一个想法:在 urls.py 中,我实际上可以在模式中对DOMAIN名称进行硬编码。因此,不要使用 kwarg &lt; domain&gt;:

urlpatterns = patterns('',
    url(r'^(?P<domain>[\w-]+)/(?P<slug>[\w-]+)/(?P<version>\d{1})/$', MyMixin.as_view(
            queryset=Docs.objects.all()
        ),
    )),
) 

并在视图中使用 kwarg作为逻辑确定器(对于if / else),我可以执行以下操作:

urlpatterns = patterns('',
    url(r'^federated/(?P<slug>[\w-]+)/(?P<version>\d{1})/$', MyListViewMixin.as_view(
            queryset=Docs.objects.all()
        ),
    )),
    url(r'^nonfederated/(?P<slug>[\w-]+)/$', MyDetailViewMixin.as_view(
            queryset=Docs.objects.all()
        ),
    )),
)

但是,我不知道有多少文档会被版本化,有多少文档不会被版本化。我需要尽可能通用(借口双关语)。提前谢谢。

1 个答案:

答案 0 :(得分:1)

我没有将ListViewDetailView混合到一个视图中(这在概念上会很混乱,难以维护),我建议将所有视图设计为将其视为版本并将未版本的视图视为版本为1(或类似的未指定版本号)的版本。

在未联合网站中,网址/path/to/docs/<DOMAIN>/<SLUG>/的行为与访问/path/to/docs/<DOMAIN>/1/<SLUG>/的行为相同。

在联盟网站中,网址/path/to/docs/<DOMAIN>/<SLUG>/会显示可用版本的列表(作为ListView)。

您可以使用执行以下操作的视图实现上述行为:

  • 检查此域名的可用版本数量
  • 如果只有一个,请重定向到/path/to/docs/<DOMAIN>/<LATEST_VERSION>/<SLUG>/
  • 如果有多个,请显示可用版本的列表,并让用户选择要访问的版本。

未联合网站只是一个只有一个版本的文档的网站。如果将来发生这种变化,那么您也可以轻松地将它们转换为版本化的文档。