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
对象上(这样您的模板也可以正确解析)。
编辑:我正在使用 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
对象上(这样您的模板也可以正确解析)。