首页 文章

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

提问于
浏览
0

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

/path/to/docs/<DOMAIN>/

这允许您查看该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/

unversioned docs 的情况下这很简单 . 但是,在另一个DOMAIN中(我们称之为"federated")我 do 有不同版本的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关于混合GCBV,特别是w.r.t.的文件warns . get_context_data() .

我在我的Mixin内部做的是查看DOMAIN名称,并在此基础上将请求分叉到ListView(对于版本化文档)或DetailView(对于非版本化文档) . 我搜遍了Django文档,但没有看到任何这方面的例子 . 谁能帮我吗?

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

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()
        ),
    )),
)

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

1 回答

  • 1

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

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

    在联合网站中,URL /path/to/docs/<DOMAIN>/<SLUG>/ 将显示可用版本的列表(作为 ListView ) .

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

    • 检查此域可用的版本数量

    • 如果只有一个,则重定向到 /path/to/docs/<DOMAIN>/<LATEST_VERSION>/<SLUG>/ .

    • 如果有多个,则显示可用版本的列表,并让用户选择要访问的版本 .

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

相关问题