如何在可重用的应用程序中将命名空间 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】:根据我对这个问题的理解:
您可以在应用的 urls.py 文件中添加应用名称在 Django 2.1.7 中
# 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' %
我认为我们应该
-
创建一个视图返回所有
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 结构
如何在可扩展的listview android中将孩子添加到特定的父母