Django 基于状态的 url 路由

Django state-based url routing

您好!

我希望我正在开发的 django 应用程序能够将 URL 路由到基于 URL 字符串之外的逻辑的响应。

我希望能够考虑应用程序的状态(登录用户及其会话、数据库内容)。这意味着两个用户可以访问完全相同的 URL,但根据他们拥有的帐户类型(例如),他们会收到不同的响应。

一个例子

假设我的应用有 UserAdmin 用户 class。他们都会经常访问 http://some-domain.com/dashboard,但他们会在那里看到 完全 不同的东西。此外,还有 dashboard 之外的子 url,例如 /dashboard/comments/dashboard/friends。同样,这些将是完全不同的视图,具体取决于用户 class。

目前我是这样做的:

(urls.py)

urlpatterns = [
    url(r'^dashboard/', include([
        url(r'^$', render_dashboard),
        url(r'^settings/$', render_dashboard_settings),
        url(r'^friends/$', render_dashboard_friends),
    ])),
]

此设置的问题是无法考虑当前用户。它仍然可以工作,因为我可以将各种用户帐户路由到同一个模板,并在那里使用 {% if ... %} 语句为不同的用户提供不同的内容。在对 django.shortcuts.render 的调用中,我还可以使应该呈现为动态的模板的名称。但这些都不是我想要的。我希望能够在较早的 URL 映射级别区分用户。

我的问题

做的 想做的是扩展 url 方法的功能以考虑状态,并根据该功能进行路由。理想情况下,像这样:

urlpatterns = [
    user_class_based_url(r'', {

        'Admin': include([
            url(r'^dashboard/', include([
                url(r'^$', render_admin_dashboard),
                url(r'^settings/$', render_admin_dashboard_settings),
                url(r'^friends/$', render_admin_dashboard_friends),
            ])),
        ]),

        'User': include([
            url(r'^dashboard/', include([
                url(r'^$', render_user_dashboard),
                url(r'^settings/$', render_user_dashboard_settings),
                url(r'^friends/$', render_user_dashboard_friends),
            ])),
        ]),

        'SomeOtherUserClass': include([.....]),
    }),
]

现在,不同的渲染器函数正在为相同的 url 但不同的用户 class 调用。不幸的是,user_class_based_url 是我完全编造的。理想情况下,user_class_based_url 是我可以编写的自定义函数。这样我就可以编写其他类似的函数,以其他方式考虑应用程序的状态。

问题:有什么方法可以获得此功能?

回应"you shouldn't even be designing it this way"

我给出的例子是为了更快地表达我的问题。我想要我所描述的功能,因为它在很多方面对我正在构建的应用程序都非常有帮助,而且我相信它会是比替代方法更好的方法。

备注

我已经在使用django rest framework,万一可以用来实现这个设计。

目前在 Django 中没有任何方法可以做到这一点。最近,this discussion 关于为 url 调度程序创建一个新的 API,但任何更改都将在 Django 的未来版本中进行。

如果您希望同一 URL 模式使用不同的模板,请不要在 urls.py 中对模板进行硬编码。相反,路由到 views.py 中的 view function (or, alternatively, to a class-based view),它会根据您的条件分派到不同的模板。这正是 views.py 的用途以及通常的使用方式。

关于如何将 URL 路由到视图函数,最好参考第 1 部分的 Django tutorial part 3. (If you're learning Django, you might want to start。)

调整 the example 从教程中引入 render 快捷方式开始,分派到不同模板的视图可能如下所示:

from django.shortcuts import render

from .models import Question


def index(request):
    if request.user.is_admin():
        return render(request, 'polls/admin-index.html', {})
    else:
        latest_question_list = Question.objects.order_by('-pub_date')[:5]
        context = {'latest_question_list': latest_question_list}
        return render(request, 'polls/index.html', context)