【问题标题】:Django state-based url routingDjango 基于状态的 url 路由
【发布时间】:2015-06-02 18:29:24
【问题描述】:

你好!

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

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

一个例子

假设我的应用有 UserAdmin 用户类。他们俩都会经常访问http://some-domain.com/dashboard,但他们会在那里看到完全不同的东西。此外,dashboard 之外还会有子 URL,例如 /dashboard/comments/dashboard/friends。同样,根据用户类别,这些视图将完全不同。

目前我在做这样的事情:

(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,但不同的用户类。不幸的是,user_class_based_url 是我完全编造出来的。理想情况下,user_class_based_url 将是我可以编写的自定义函数。这样我就可以编写其他类似的函数,以其他方式考虑应用程序的状态。

问题:我有什么办法可以得到这个功能?

回应“你甚至不应该这样设计”

我给出的示例旨在让我的问题更快得到解决。我想要我所描述的功能,因为它在很多方面对我正在构建的应用程序都非常有帮助,而且我相信它会是一种比替代方法更好的方法。

注意

我已经在使用 django rest 框架,以防可以用来实现这个设计。

【问题讨论】:

  • 如果有人感兴趣,我已经用完全自定义的代码解决了这个问题,它允许我使用我所说的在这个问题中寻找的模式进行开发。如果有人愿意,我会将其发布为答案。

标签: python django url-routing


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果您想为相同的 URL 模式使用不同的模板,请不要对 urls.py 中的模板进行硬编码。相反,路由到views.py 中的view function(或者,路由到class-based view),它会根据您的标准分派到不同的模板。这正是views.py 的用途以及它通常的使用方式。

    关于如何将 URL 路由到视图函数,最好咨询Django tutorial part 3。 (如果你正在学习 Django,你可能想在第 1 部分start。)

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

    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)
    

    【讨论】:

    • 但在我看来,url 路由逻辑不是“视图”,因此我自然会犹豫是否将其放入views.py。我更愿意弄清楚我最终想要在任何视图之外访问哪个视图。仍然 - 我对你将如何使用视图来实现这一点感兴趣。你能发布一些示例代码吗?谢谢!
    • 不要过多地阅读框架概念的名称。 Django 的“视图”大致对应于 Rails 的“控制器”,而 Django 的“模板”更像是 Rails 的“视图”。其他 web 、前端和 GUI 框架使用相同的术语,但含义不同,可能没有一个与这些术语在完善的 Model-View-Controller pattern 中的含义完全相同。在学习一个框架时,要习惯它的概念和术语,但请记住它们可能是特定于框架的。
    • 酷,明白。不过,我会喜欢一些基本的示例代码,只是为了开始!我已经阅读了您链接的视图教程,我希望在利用视图解决这个特定的设计问题方面得到一些帮助。
    • 请记住,视图只是接收请求并返回响应的函数。制作一个“路由器视图”是完全可以接受的,它只是根据某些条件返回另一个视图的响应。在 url 调度程序本身中允许这样做的新 API 将在 1.9 或 2.0 之前准备好。
    • 好的,很酷。我意识到这是一种选择——如果我实现自己的 url 处理方法,我担心会丢失 django 的反向 url 能力,例如用于{% url 'some-url-name' %}。我想我也可以自己重写那个功能......?你认为失去 reverse 功能值得吗?
    猜你喜欢
    • 2021-10-03
    • 2020-01-12
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2023-01-13
    • 2020-01-21
    • 2017-07-27
    • 2018-12-28
    相关资源
    最近更新 更多