Django -当re_path找到一个匹配项,但将其交给一个“include”的urls.py文件时,会发生什么?

kuuvgm7e  于 2023-08-08  发布在  Go
关注(0)|答案(1)|浏览(100)

我正在开发一个Django站点,但对Django和Python来说相当陌生。
我遇到了一个“更高级别”的urls.py文件,它使用re_path为子目录做正则表达式匹配,然后include将每个子目录传递给它自己的urls.py文件。大概是这样的:

urlpatterns = [
    re_path(r'^SUBDIR1/.*$(?i)', include('subdir1.urls')),
    re_path(r'^SUBDIR2/.*$(?i)', include('subdir2.urls')),
    re_path(r'^SUBDIR3/.*$(?i)', include('subdir3.urls'))
]

字符串
然后每个子目录的urls.py基本上只有一个路径/视图连接:

urlpatterns = [
    path('', views.main_view, name='index')
]


在其中一个中,我试图设置第二个URL以转到不同的视图:

urlpatterns = [
    path('', views.main_view, name='index'),
    path('my_new_view/<parameter>/', views.my_new_view, name='my_new_view')
]


但是我似乎无法调用视图,每次我尝试一个应该匹配我的新模式的URL时,我只是再次得到主视图。我猜我不太明白当re_path找到一个匹配并将其交给包含的urls.py文件时会发生什么。我知道正则表达式基本上是在说“匹配子目录名,一个正斜杠,然后再匹配任意数量的字符”,但是“匹配”字符串会发生什么呢?完整匹配是否传递给include文件进行进一步处理,或者正则表达式会吞噬匹配并像空字符串或null或其他东西一样传递给include文件?
如何让正则表达式与子目录模式匹配,同时又传递足够的信息给第二个urls.py文件以触发新视图?
根据@Homer6的回答:
Django中的include()函数在匹配结束的位置拆分URL字符串,并将字符串的剩余部分传递给包含的URLconf进行进一步处理。
我认为我的新视图没有被触发的原因是所有的正则表达式都设置为在子目录后面有.*$,这样就可以“匹配”整个URL * 到字符串 * 的末尾,所以没有任何东西被分割出来并传递到下一个URLconf。
给定一个URL,例如

http://hostname/subdir1/my_new_view/some_param_value


我想要的是让subdir1/匹配正则表达式,并让my_new_view/some_param_value通过include传递到下一个URLconf。
我把它变成这样:

re_path(r'^subdir1/', include('subdir1.urls'))


不起作用的部分是(?i)大小写不敏感标志。Regex 101网站抱怨它在末尾,并说它应该在开头,但如果我尝试r'(?i)^subdir1/',Django不喜欢它。Django也不喜欢r'^subdir1/(?i)'。Django似乎只有在 after a $时才接受这个标志,比如:r'^subdir1/$(?i)',但这是“字符串结束”的位置指示符,所以如果URL中有更多的字符串,而不仅仅是“subdir1/”,它就完全不匹配了。
所以我最后选择了

urlpatterns = [
    re_path(r'^SUBDIR1/', include('subdir1.urls')),
    re_path(r'^subdir1/', include('subdir1.urls'))
]


这并不理想,但可能涵盖了几乎所有的可能性。实际子目录字符串不是单词,它们只是简短的首字母缩写,所以它们不太可能是大小写混合的。

yr9zkbsy

yr9zkbsy1#

Django中的include()函数在匹配结束的位置拆分URL字符串,并将字符串的剩余部分传递给包含的URLconf以进行进一步处理。当一个请求进来时,Django从ROOT_URLCONF的顶部开始,沿着模式列表向下移动,在第一个匹配的模式处停止。include()函数将URL中匹配到该点的任何部分剪掉,并将剩余的字符串发送到包含的URLconf中。
在您的示例中,re_path(r'^SUBDIR1/.*$(?i)', include('subdir1.urls'))中有一个正则表达式模式,该模式匹配以“SUBDIR 1/"开头的任何URL,然后匹配任意数量的字符,然后切换到subdir1.urls
事情是这样的:
1.一个请求进来了,假设是“SUBDIR 1/my_new_view/123/”

  1. Django从根URLconf的顶部开始,找到第一个匹配项:re_path(r'^SUBDIR1/.*$(?i)', include('subdir1.urls'))
  2. Django删除了URL中与“SUBDIR 1/"匹配的部分,因此剩下的字符串是“my_new_view/123/”
    1.剩余的字符串被传递给subdir1.urls以进行进一步处理。
    因此,您面临的问题可能与re_path切换无关,而是与如何在子目录的urls.py中定义URL有关。
    您的subdir1.urls文件应该如下所示:
urlpatterns = [
    path('', views.main_view, name='index'),
    path('my_new_view/<parameter>/', views.my_new_view, name='my_new_view')
]

字符串
如果您仍然面临这个问题,您可能需要检查:
1.您的视图函数my_new_viewviews.py中正确定义,并且使用正确的参数。

  1. URL模式中的<parameter>在视图函数中正确使用。
    1.确保您已经在urls.py文件的顶部导入了必要的模块。

相关问题