【问题标题】:Page 404's depending on its position in 'urlpatterns' - why?页面 404 取决于它在“urlpatterns”中的位置 - 为什么?
【发布时间】:2019-09-13 22:15:58
【问题描述】:

所以我正在尝试呈现具有正确配置的 generic.CreateView 的页面“提交”。此 URL 模式呈现良好:

from django.contrib import admin
from django.urls import include, path
from curate import views

urlpatterns = [
    path('', views.SetListView.as_view(), name='set_list'),
    path('new/', views.ItemListView.as_view(), name='new_list'),
    path('<int:pk>/edit', views.ItemEditView.as_view(), name='item_edit'),
    path('<int:pk>/delete', views.ItemDeleteView.as_view(), name='item_delete'),
    path('submit/', views.SubmitItem.as_view(), name='submit_item'),
    path('<slug>/', views.ItemDetailView.as_view(), name='item_detail'),
    path('<int:pk>/', views.ItemDeleteView.as_view(), name='item_detailPK'),
    path('<slug>/', views.SetDetailView.as_view(), name='set_detail'),
]

但由于某种原因,如果提交视图在列表中的其他位置,即如下所示,就像它在 ItemDetailView.as_view() url 下方,那么它不会呈现,它只是 404。

from django.contrib import admin
from django.urls import include, path
from curate import views

urlpatterns = [
    path('', views.SetListView.as_view(), name='set_list'),
    path('new/', views.ItemListView.as_view(), name='new_list'),
    path('<int:pk>/edit', views.ItemEditView.as_view(), name='item_edit'),
    path('<int:pk>/delete', views.ItemDeleteView.as_view(), name='item_delete'),
    path('<slug>/', views.ItemDetailView.as_view(), name='item_detail'),
    path('submit/', views.SubmitItem.as_view(), name='submit_item'),
    path('<int:pk>/', views.ItemDeleteView.as_view(), name='item_detailPK'),
    path('<slug>/', views.SetDetailView.as_view(), name='set_detail'),
]

奇怪的是,ItemDetailView 渲染良好 - 这为我页面上的所有项目提供动力?

【问题讨论】:

  • 可能不相关,但您有两个具有相同模式的网址'&lt;slug&gt;/'
  • &lt;slug&gt;/一样,&lt;int:pk&gt;/永远不会被使用,因为它会被&lt;slug&gt;/匹配。
  • 我使用模板中的 PK 视图来“增加”文章 - 作为“下一个”视图。这是暂时的,但现在可以使用。
  • 我认为您弄错了,对/5/ 的请求将由ItemDetailViewslug=5 匹配,而不是ItemDeleteViewpk=5 匹配。无论如何,Item*Delete*Viewname='item_*detail*PK' 之间存在不匹配,您应该检查一下。

标签: python django url path url-pattern


【解决方案1】:
path('<slug>/', views.ItemDetailView.as_view(), name='item_detail'),
path('submit/', views.SubmitItem.as_view(), name='submit_item'),

item_detail 高于submit_item 时,对/submit/ 的请求与'&lt;slug&gt;/' 匹配,因此请求由ItemDetailView 处理。

您没有带有 slug="submit" 的项目,所以这会给出 404。

Django URL 解析器使用第一个匹配的 URL 模式。如果第一个匹配返回 404,它不会尝试其他 URL 模式。

submit_item 高于item_detail 时,/submit/ 的请求由SubmitItem 视图正确处理。

【讨论】:

  • 谢谢 - 这真的很明显,但我的脑袋想不通。而不是重新编写代码,我可以移动 url 模式的顺序,这样逻辑就可以工作了。可能有更好的方法来构建事物,但这很有效。谢谢!
  • 您的选择是为您的 URL 模式选择合适的顺序,或者调整路径以使其不会冲突(例如,您可以使用 'by_slug/&lt;slug&gt;/' 使其不会与 @987654333 冲突@
【解决方案2】:

这是因为 url 模式 - &lt;slug&gt;/。如果此模式高于submit,则 django 会尝试查找slug=submit。而且由于数据库中不存在它,因此您会得到 404。

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 1970-01-01
    相关资源
    最近更新 更多