如何在可重用的应用程序中将命名空间 url 与 django 一起使用

Posted

技术标签:

【中文标题】如何在可重用的应用程序中将命名空间 url 与 django 一起使用【英文标题】:How to use namespace urls with django in a reusuable app 【发布时间】:2011-03-10 12:04:06 【问题描述】:

我有一个 django 应用程序,一个论坛应用程序,它带有模板。在这些模板中,有指向应用程序部分的 url。例如,thread_list 模板具有指向每个线程的链接,如下所示:

% for thread in threads %
    <a href="% url forum_thread thread %">thread.title</a>
% endfor %

问题是,我不太喜欢称我的网址为“forum_thread”。我更喜欢“线程”并使用 django 的命名空间功能。 “forum_thread”可能会在项目的其他地方使用(命名空间冲突)。所以它看起来像这样:

% for thread in threads %
    <a href="% url forum:thread thread %">thread.title</a>
% endfor %

但这感觉不是正确的方法。这里的文档有点不清楚。

我希望此应用可重复使用且易于配置。但我也想使用最好的标准。我不想让用户指定他们自己的命名空间名称,然后让他们编辑每个模板中的每个 url。

我应该如何在这个应用程序中做网址?

【问题讨论】:

我也有同样的困境!撞! 你有过什么吗?我遇到了同样的问题,不知道应该怎么做。 【参考方案1】:

据我所知,您应该可以按照您的描述使用 % url forum:thread thread %。命名空间似乎总是用两个变量定义,命名空间和 app_name。

如果您随后在 urls.py 中执行以下操作:

url(r'^/forum/', include('forum.urls', namespace='forum', app_name='forum')),
url(r'^/foo/', include('forum.urls', namespace='foo', app_name='forum')),
url(r'^/bar/', include('forum.urls', namespace='bar', app_name='forum')),

据我了解,这定义了应用程序“forum”、“foo”、“bar”的 3 个实例和默认值(具有 namespace==app_name)。

当你反转 forum:thread 时,它使用当前上下文来确定使用哪一个 - 如果你在命名空间 'foo' 中,它将使用它,否则它将回退到默认值。

如果有人能够阐明 Django 如何决定“当前”命名空间/应用程序是什么,那将非常有帮助。我目前将其归类为“黑魔法”。

对命名空间和 app_name 之间的实际区别进行一些澄清也会有所帮助 - 我可能完全颠倒了这一点。当前的文档非常模糊。

注意:我为初始请求提供了此功能,但我目前无法为 AJAX 请求提供此功能 - 出于某种原因,这些请求始终使用默认实例。

【讨论】:

现在在文档中指定了它,看起来你已经正确了:docs.djangoproject.com/en/dev/topics/http/urls/… 我认为没有必要指定app_name='forum',除非你想使用与模块名称不同的东西。我猜如果不适用于 AJAX 请求,可能是因为您以不同的方式呈现响应(可能不使用模板或不使用 RequestContext),因此在反转 url 时需要手动指定当前应用程序。 问题是这个 url 只能包含在根 url 中。 IE。有一个 app 和一个 site 应用程序包含在根 url app/urls.py 中:url(r'^/site/', include('site.urls', namespace='site', app_name='site'), site i> 应用包括论坛:url(r'^/forum/', include('forum.urls', namespace='forum', app_name='forum')) 它破坏了论坛,因为它的网址不能反转为“论坛:*”而是“站点:论坛”*”【参考方案2】:

这可能是一个简单的语法错误。我在关注Django Tutorial,并且不正确地更改了 mysite/urls.py。原文语法:

url(r'^polls/', include('polls.urls')),

想要的改变:

url(r'^polls/', include('polls.urls', namespace="polls")),

我做了什么:

url(r'^polls/', include('polls.urls'), namespace="polls"),

更正语法解决了问题。

【讨论】:

【参考方案3】:

根据我对这个问题的理解:

在 Django 2.1.7 中

您可以在应用的 urls.py 文件中添加应用名称
# app's urls.py
from django.urls import path
from . import views

app_name = 'forum'
urlpatterns = [
    path('thread/', views.mark_done, name='thread')
]

在主 urls.py 中

# urls.py
....

urlpatterns = [
    path('forum/', include('forum.urls')),
]

那么你可以在你的模板中使用% url 'forum:thread' %

如果你想在 for 循环中使用它

我认为我们应该

    创建一个视图返回所有 threads 作为上下文 然后添加该视图的路径
...
path('thread/<int:pk>', views.mark_done, name='thread')

模板中的网址会喜欢:

% for thread in threads %
    <a href="% url 'forum:thread' thread.id %">thread.title</a>
% endfor %

【讨论】:

以上是关于如何在可重用的应用程序中将命名空间 url 与 django 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何跨命名空间和平台伪造库(GDI 到 Xamarin.Forms),例如重用 Color 结构

如何使用打字稿在可重用组件中导入html样式属性?

如何在可扩展的listview android中将孩子添加到特定的父母

如何在C ++中将枚举导入不同的命名空间?

Vue TSX - 如何告诉 Typescript 在可重用组件中允许使用 HTML 属性?

如何在 PLSQL 中将命名空间添加到 XML 输出