django-cms url 与 Slug at Root
Posted
技术标签:
【中文标题】django-cms url 与 Slug at Root【英文标题】:django-cms urls with Slug at Root 【发布时间】:2013-09-29 09:11:19 【问题描述】:在我的 url.py 我有:
urlpatterns += patterns('',
url(r'^tinymce/', include('tinymce.urls')),
url(r'^', include('cms.urls')),
url(r'^journal/', include('zinnia.urls')),
url(r'^comments/', include('django.contrib.comments.urls')),
)
和
urlpatterns += patterns('',
url(r'^(?P<slug>[-\w\d]+)/$', PremiumListingDetailView.as_view(), name='premium_listing'),
)
我想在http://www.example.com/slug 获得高级列表的 url,以显示 DetailView。如果我将高级列表的 url 放在 django-cms 之前,页面会加载,但不会显示其余的 cms 页面,例如转到 http://www.example.com/about 会抛出 404。如果我把它放在 cms 的包含 url 之后,转到 http://www.example.com/slug 将不起作用。
我应该如何构建 urls 文件以实现我所需要的?目前,我在列表 URL 前附加一个波浪号:url(r'^~(?P<slug>[-\w\d]+)/$, ...)
,这可能不是最佳解决方案。
【问题讨论】:
请添加cms.urls代码 【参考方案1】:应用程序 x 的 url 与应用程序 y 的模式匹配。视图无法匹配 slug 并返回 404 未找到。
模式r'^'
或r'^(?P<slug>[-\w\d]+)/$'
应该排在最后,因为它会捕获任何东西。仅使用两者之一,因为它们匹配相同(请参阅 cms.urls)。考虑一个带有 cmets 的 PremiumListingDetailView 对象。此时它会劫持 cmets 应用程序。将宽匹配模式放在最后,重要的模式总是优先。
修复模式冲突的简单(且面向未来)的方法是使模式独一无二:
url(r'^cms/', include('cms.urls')), # Added cms/
现在,如果 slug 不是 tinymce、cms、journal 或 cmets,它最终会出现在 PremiumListingDetailView 中。
或者,您可以使 PremiumListingDetailView 模式独一无二(您使用波浪号完成此操作):
url(r'^list/(?P<slug>[-\w\d]+)/$', # Added list/
PremiumListingDetailView.as_view(),
name='premium_listing'),
url(r'^', include('cms.urls')), # CMS comes after.
但是如果 cms 在list/something/
有视图呢?无法访问 cms 视图。该请求将由 PremiumListingDetailView 处理,并且 slug something 将不存在,从而导致 404。
从技术上讲,您可以将 PremiumListingDetailView 模式放在 cms.urls 中,在那里您可以精细控制何时匹配 cms 或 PremiumListingDetailView 模式,但模式仍然可能发生冲突。这将违反松散耦合原则。它会咬你。
结论:在唯一的网址中包含应用。确保应用程序中的每个模式都是独一无二的。宽匹配模式应该排在更重要的模式之后。
【讨论】:
大家好,感谢您简洁明了的回答。你的结论和我想的一模一样,尤其是模式完全相同的劫持部分。感谢您指出如何在未来证明 url 以及可能意外出现冲突的位置。以上是关于django-cms url 与 Slug at Root的主要内容,如果未能解决你的问题,请参考以下文章
django-cms:反向 url 到一个/另一个 apphook - 多语言
如果 URL 与 slug 不匹配,则规范链接和 301 重定向