Django 将 reverse() 与包含相同应用程序的多个 URL 一起使用

Django Using reverse() with multiple URLs that include the same app

编辑:我正在使用 rest_framework.reverse 并提供应用程序名称而不是反向查找的命名空间。一个反向调用的例子是:

reverse('api_app:system-detail', kwargs={...}, request=self.context.get('request'))

所以我有一个只有一个应用程序的 django 项目,我有两个不同的 url 模式映射到这个应用程序。我目前主要使用它,但是在少数情况下使用 reverse() 会导致错误的命名空间。我的基地 urls.py 看起来像这样:

from django.conf.urls import url, include
from django.views.generic.base import RedirectView


urlpatterns = [
    url(r'^api/', include('api_project.api_app.urls', 
    namespace='api')),
    url(r'^beta/api/', include('api_project.api_app.urls', 
    namespace='beta')),
    url(r'^$', RedirectView.as_view(url='api', permanent=False), 
    name='index')
]

编辑:api_app.urls 看起来像:

from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from . import views
from rest_framework.schemas import get_schema_view

schema_view = get_schema_view(title="Schema")


app_name = 'api_app'

urlpatterns = [
url(r'^$', views.APIRoot.as_view(), name='api-root'),
url(r'^schema/$', schema_view, name'api-schema'),
....

在大多数情况下,逆向会按预期工作,例如使用 /beta/endpoint 在页面上有如下链接:

/beta/endpoint/example

但是,在少数情况下,使用 /beta/endpoint 的链接如下:

/api/endpoint/different-example

我的问题不是反向如何确定要使用哪个命名空间,而是这是为同一应用程序使用两个命名空间的适当方式吗?这是我应该完全不同的方法吗?

到目前为止,我的大部分研究都没有取得太大的成功,所以我认为这可能从根本上说是错误的方法。

如果这种方法没问题,那么我很好奇为什么 reverse 在哪个命名空间中不一致 returns。

reversing namespaced URLs 上的文档向您展示了发生的情况。在您的情况下,您将同一个应用程序实例化两次,一次使用实例命名空间 api,一次使用实例命名空间 beta.

您的应用程序命名空间是 api_app,由包含的 urls.py 文件中的 app_name 变量定义。所以它与两个实例命名空间中的任何一个都不匹配,这意味着没有默认应用程序实例。

因此,在您的情况下,URL 解析器将主要解析为情况 4:如果您未在视图中指定 current_app,它将解析为最后部署的实例(意思是最后注册的),即"beta".

您应该在您的视图中指定您的 current_app,无论是在使用 reverse 还是在 request 对象上(这样您的模板也可以正确解析)。