关于python:基于Django状态的URL路由

Django state-based url routing

你好!

我很喜欢我正在开发的Django应用程序,用于将URL路由到基于URL字符串以外的逻辑的响应。

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

一个例子

说我的应用程序具有UserAdmin用户类。他们俩都会经常访问http://some-domain.com/dashboard,但是他们在那里会看到完全不同的事物。此外,除了dashboard之外,还会有子网址,例如/dashboard/comments/dashboard/friends。同样,根据用户类别,这些视图将完全不同。

目前我正在执行以下操作:

(urls.py)

1
2
3
4
5
6
7
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方法的功能以考虑状态,并基于该功能进行路由。理想情况是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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调用了不同的渲染器功能,但是用户类不同。不幸的是,user_class_based_url是我完全弥补的。理想情况下,user_class_based_url是我可以编写的自定义函数。这样,我可以编写其他类似的功能,以其他方式考虑应用程序的状态。

问题:有什么办法可以获取此功能?

针对"您甚至不应该这样设计"

我举的例子旨在使我的问题更快地得到解决。我想要我描述的功能,因为它在许多方面都对我正在构建的应用程序有极大的帮助,而且我敢肯定,这是比替代方法更好的方法。

注意

我已经在使用django rest框架,以防可以用于实现此设计。


如果要为同一URL模式使用不同的模板,请不要在urls.py中对模板进行硬编码。而是,路由到views.py中的视图函数(或替代地,基于类的视图),该函数根据您的条件将其分发到不同的模板。这正是views.py的用途以及通常的用法。

有关如何将URL路由到视图函数,最好参考Django教程的第3部分。(如果您正在学习Django,则可能要从第1部分开始。)

适应本教程中引入render快捷方式时的示例,分派到不同模板的视图可能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
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)


目前Django中没有任何方法可以执行此操作。最近,关于为URL调度程序创建新API的讨论已经进行了,但是任何更改都将在Django的未来版本中进行。