Django URL 命名空间 - 模板必须知道它的命名空间?
Django URL namespaces - the template has to know its namespace?
我一直在修补(我的第一个)Django 项目,该项目从 Django 1.6 开始,最近刚刚转移到 Django 1.8。我也一直在研究 Django 模式和最佳实践,学习我应该如何构建它:-)
我的项目有几个子应用程序和一个典型的主应用程序 urls.py,其行如下:
(r'', include('noc.apps.frontpage.urls')),
在每个应用程序中,我都在所有 URL 名称前加上应用程序名称前缀,例如frontpage_edit_page 并在整个模板中使用 {% url %}
在视图之间引用。
然后我阅读了有关 URL 名称空间的信息,并认为我可以对我的 URL 名称进行去丑化处理。正如我最初解释的那样,如果我在主 urls.py 中为每个 include() 添加一个命名空间,一切都会像以前一样运行,因为引用的 URL 名称将全部由 'local' 应用程序。但它似乎不是那样工作的。
主要是这个urls.py:
(r'', include('noc.apps.frontpage.urls', namespace='frontpage', app_name='frontpage')),
这在应用程序中 urls.py:
url(r'^frontpage/edit/(?P<slug>[A-Za-z0-9]+)$', views.edit_page, name='front_page_edit_page'),
和 {% url 'front_page_edit_page' slug=page.slug %}
在该应用程序内的模板中,我得到一个 NoReverseMatch 异常,尝试了 0 URLs。
我能找到的所有示例都在讨论使用命名空间为 URL 加上前缀 - frontpage:front_page_edit_page
但是 1) 这对 URL 上的先前应用程序前缀有何改进姓名?和 2) 你怎么可能有同一个应用程序的两个实例,这应该是一个好处......所以我假设这是为了链接 between 应用程序,而不是 在 个应用程序中。
那么我缺少什么?我是否也需要在我的视图函数中嵌入 app_name 或命名空间?的确,如果我确实在我的所有 URL 名称前加上命名空间,即使在应用程序中,我也会得到一个呈现的页面,但这似乎没有意义。
你打算这样做的方式确实是将命名空间添加到 URL 标记;
{% url 'frontpage:edit_page' slug='SLUG' %}
但是最好像这样构建您的主项目 URls 文件;
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'frontpage', include('noc.apps.frontpage.urls', namespace='frontpage', app_name='frontpage')),
这样你就可以在主URLs文件中指定每个应用程序的路径,避免重复;
urlpatterns = patterns(
'noc.apps.frontpage.views',
url(r'^edit/(?P<slug>[A-Za-z0-9]+)$', 'edit_page', name='edit_page'),
有了这个,您可以为所有应用程序引入一个 RESTful URL 结构,这样您最终会得到类似的东西;
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'frontpage/', include('noc.apps.frontpage.urls', namespace='frontpage', app_name='frontpage')),
url(r'contact/', include('noc.apps.contact.urls', namespace='contact', app_name='contact')),
url(r'myapp/', include('noc.apps.myapp.urls', namespace='myapp', app_name='myapp')),
那么您所有的应用程序都可以遵循类似的结构;
urlpatterns = patterns(
'noc.apps.contact.views',
url(r'^$', 'index', name='index'),
url(r'^add/$', 'add', name='add'),
url(r'^edit/(?P<slug>[A-Za-z0-9]+)$', 'edit', name='edit'),
urlpatterns = patterns(
'noc.apps.myapp.views',
url(r'^$', 'index', name='index'),
url(r'^add/$', 'add', name='add'),
url(r'^edit/(?P<slug>[A-Za-z0-9]+)$', 'edit', name='edit'),
可以使用顶级命名空间实现 frontpage
的多个实例;
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'frontpage/', include('noc.apps.frontpage.urls', namespace='frontpage1', app_name='frontpage')),
url(r'frontpage/', include('noc.apps.frontpage.urls', namespace='frontpage2', app_name='frontpage')),
这样您应该能够定位顶级实例命名空间,然后是像这样的应用程序命名空间;
{% url 'frontpage1:frontpage:edit_page' slug='SLUG' %}
{% url 'frontpage2:frontpage:edit_page' slug='SLUG' %}
但是如果你想让你的模板链接更通用,我相信你可以省略顶级命名空间,django 将解析到你必须添加到请求对象的当前应用程序。这个在Reversing Namespaced URLs
末尾有详细说明
试试这个
(r'', include('noc.apps.frontpage.urls', namespace = 'abc')),
然后在您的模板中:
{% url 'abc:frontpage:front_page_edit_page' slug=page.slug %}
供大家参考。
这对我有用,Django 2.2.2
# project urls.py
# DjpollsConfig is my app config
from djpolls.apps import DjpollsConfig
djpolls_app_name = DjpollsConfig.name
urlpatterns = [
path(djpolls_app_name, include('djpolls.urls', namespace='djpolls_app_name'))
]
# app urls.py
from django_proj.urls import djpolls_app_name
app_name = djpolls_app_name
# app template
{% url 'djpolls_app_name:detail' question.id %}
希望对您有所帮助!
我一直在修补(我的第一个)Django 项目,该项目从 Django 1.6 开始,最近刚刚转移到 Django 1.8。我也一直在研究 Django 模式和最佳实践,学习我应该如何构建它:-)
我的项目有几个子应用程序和一个典型的主应用程序 urls.py,其行如下:
(r'', include('noc.apps.frontpage.urls')),
在每个应用程序中,我都在所有 URL 名称前加上应用程序名称前缀,例如frontpage_edit_page 并在整个模板中使用 {% url %}
在视图之间引用。
然后我阅读了有关 URL 名称空间的信息,并认为我可以对我的 URL 名称进行去丑化处理。正如我最初解释的那样,如果我在主 urls.py 中为每个 include() 添加一个命名空间,一切都会像以前一样运行,因为引用的 URL 名称将全部由 'local' 应用程序。但它似乎不是那样工作的。
主要是这个urls.py:
(r'', include('noc.apps.frontpage.urls', namespace='frontpage', app_name='frontpage')),
这在应用程序中 urls.py:
url(r'^frontpage/edit/(?P<slug>[A-Za-z0-9]+)$', views.edit_page, name='front_page_edit_page'),
和 {% url 'front_page_edit_page' slug=page.slug %}
在该应用程序内的模板中,我得到一个 NoReverseMatch 异常,尝试了 0 URLs。
我能找到的所有示例都在讨论使用命名空间为 URL 加上前缀 - frontpage:front_page_edit_page
但是 1) 这对 URL 上的先前应用程序前缀有何改进姓名?和 2) 你怎么可能有同一个应用程序的两个实例,这应该是一个好处......所以我假设这是为了链接 between 应用程序,而不是 在 个应用程序中。
那么我缺少什么?我是否也需要在我的视图函数中嵌入 app_name 或命名空间?的确,如果我确实在我的所有 URL 名称前加上命名空间,即使在应用程序中,我也会得到一个呈现的页面,但这似乎没有意义。
你打算这样做的方式确实是将命名空间添加到 URL 标记;
{% url 'frontpage:edit_page' slug='SLUG' %}
但是最好像这样构建您的主项目 URls 文件;
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'frontpage', include('noc.apps.frontpage.urls', namespace='frontpage', app_name='frontpage')),
这样你就可以在主URLs文件中指定每个应用程序的路径,避免重复;
urlpatterns = patterns(
'noc.apps.frontpage.views',
url(r'^edit/(?P<slug>[A-Za-z0-9]+)$', 'edit_page', name='edit_page'),
有了这个,您可以为所有应用程序引入一个 RESTful URL 结构,这样您最终会得到类似的东西;
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'frontpage/', include('noc.apps.frontpage.urls', namespace='frontpage', app_name='frontpage')),
url(r'contact/', include('noc.apps.contact.urls', namespace='contact', app_name='contact')),
url(r'myapp/', include('noc.apps.myapp.urls', namespace='myapp', app_name='myapp')),
那么您所有的应用程序都可以遵循类似的结构;
urlpatterns = patterns(
'noc.apps.contact.views',
url(r'^$', 'index', name='index'),
url(r'^add/$', 'add', name='add'),
url(r'^edit/(?P<slug>[A-Za-z0-9]+)$', 'edit', name='edit'),
urlpatterns = patterns(
'noc.apps.myapp.views',
url(r'^$', 'index', name='index'),
url(r'^add/$', 'add', name='add'),
url(r'^edit/(?P<slug>[A-Za-z0-9]+)$', 'edit', name='edit'),
可以使用顶级命名空间实现 frontpage
的多个实例;
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'frontpage/', include('noc.apps.frontpage.urls', namespace='frontpage1', app_name='frontpage')),
url(r'frontpage/', include('noc.apps.frontpage.urls', namespace='frontpage2', app_name='frontpage')),
这样您应该能够定位顶级实例命名空间,然后是像这样的应用程序命名空间;
{% url 'frontpage1:frontpage:edit_page' slug='SLUG' %}
{% url 'frontpage2:frontpage:edit_page' slug='SLUG' %}
但是如果你想让你的模板链接更通用,我相信你可以省略顶级命名空间,django 将解析到你必须添加到请求对象的当前应用程序。这个在Reversing Namespaced URLs
末尾有详细说明试试这个
(r'', include('noc.apps.frontpage.urls', namespace = 'abc')),
然后在您的模板中:
{% url 'abc:frontpage:front_page_edit_page' slug=page.slug %}
供大家参考。
这对我有用,Django 2.2.2
# project urls.py
# DjpollsConfig is my app config
from djpolls.apps import DjpollsConfig
djpolls_app_name = DjpollsConfig.name
urlpatterns = [
path(djpolls_app_name, include('djpolls.urls', namespace='djpolls_app_name'))
]
# app urls.py
from django_proj.urls import djpolls_app_name
app_name = djpolls_app_name
# app template
{% url 'djpolls_app_name:detail' question.id %}
希望对您有所帮助!