【问题标题】:Django generic class-based views - handling ListView and DetailView in a single MixinDjango 基于类的通用视图 - 在单个 Mixin 中处理 ListView 和 DetailView
【发布时间】:2012-12-31 11:05:59
【问题描述】:

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

/path/to/docs/<DOMAIN>/

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

/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 中使用单个条目来处理这两者这些类型的查询(详细信息和列表视图)。事实上,Django 文档warns 关于混合 GCBV,尤其是 w.r.t。 get_context_data().

可以在我的 Mixin 内部做的是查看 DOMAIN 名称,并在此基础上将请求分叉到 ListView(对于版本化文档)或 DetailView(对于非版本化的文档)。我已经搜索了所有 Django 文档,但没有看到任何示例。谁能帮帮我?

注意: 我确实想到了一个想法:在 urls.py 中,我实际上可以在模式中硬编码 DOMAIN 名称。所以不要使用 kwarg :

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

并在视图中使用 domain 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()
        ),
    )),
)

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

【问题讨论】:

    标签: django django-class-based-views


    【解决方案1】:

    我建议不要将ListViewDetailView 混合到一个视图中(这在概念上是一团糟且难以维护),我建议您将所有视图设计为好像它们是版本化的,并将未版本化的视图视为具有版本@ 的视图987654323@(或类似的未指定版本号)。

    在非联合网站中,URL /path/to/docs/&lt;DOMAIN&gt;/&lt;SLUG&gt;/ 的行为与访问 /path/to/docs/&lt;DOMAIN&gt;/1/&lt;SLUG&gt;/ 的行为相同。

    在联合网站中,URL /path/to/docs/&lt;DOMAIN&gt;/&lt;SLUG&gt;/ 将显示可用版本的列表(作为 ListView)。

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

    • 检查有多少版本可用于此域
    • 如果只有一个,重定向到/path/to/docs/&lt;DOMAIN&gt;/&lt;LATEST_VERSION&gt;/&lt;SLUG&gt;/
    • 如果有多个,则显示可用版本的列表并让用户选择要访问的版本。

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

    【讨论】:

      猜你喜欢
      • 2016-12-05
      • 2017-11-07
      • 2013-03-25
      • 2021-05-30
      • 2014-10-12
      • 2018-03-05
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多