Django slug的URL中的正则表达式

Yin*_*ang 13 regex django

我有2个URL,URL中有一个slug字段.

url(r'^genres/(?P<slug>.+)/$', views.genre_view, name='genre_view'),
url(r'^genres/(?P<slug>.+)/monthly/$', views.genre_month, name='genre_month'),
Run Code Online (Sandbox Code Playgroud)

第一个打开正常,但第二个给出了一个DoesNotExist错误的说法Genres matching query does not exist.

以下是我在HTML中访问第二个URL的方法

<li><a href="{% url 'genre_month' slug=genre.slug %}">Monthly Top Songs</a></li>
Run Code Online (Sandbox Code Playgroud)

我试图在视图中打印slug.genre_name/monthly相反,而不是传递它genre_name.

我认为问题在于URL中的正则表达式.知道这里有什么问题吗?

Lud*_*mer 21

Django总是使用匹配的第一个模式.对于类似于genres/genre_name/monthly您的第一个模式匹配的URL ,所以从不使用第二个.事实是正则表达式不够具体,允许所有字符 - 这似乎没有意义.

您可以颠倒这些模式的顺序,但您应该做的是使它们更具体(比较:基于通用类的视图文档中的urls.py示例):

url(r'^genres/(?P<slug>[-\w]+)/$', views.genre_view, name='genre_view'),
url(r'^genres/(?P<slug>[-\w]+)/monthly/$', views.genre_month, name='genre_month'),
Run Code Online (Sandbox Code Playgroud)

  • 要考虑的一件事是使用合理的限制字符数来匹配而不是"+"以避免溢出攻击,例如`(?P <slug> [ - \w] {1,255})`.如果你想进一步约束你想要和不匹配的东西,你甚至可以增加最小值. (4认同)

Bab*_*k K 10

我相信你也可以放弃@Ludwik建议_的模式并修改到这个版本(这是一个更简单的一个字符:)):

url(r'^genres/(?P<slug>[-\w]+)/$', views.genre_view, name='genre_view'),
url(r'^genres/(?P<slug>[-\w]+)/monthly/$', views.genre_month, name='genre_month'),
Run Code Online (Sandbox Code Playgroud)

注意,\w代表" 单词字符 ".它始终与ASCII字符匹配[A-Za-z0-9_].请注意包含下划线和数字.更多信息


Sup*_*ova 5

在 Django >= 2.0 中,slug 通过如下方式包含在 URL 中。

from django.urls import path

urlpatterns = [
    ...
    path('articles/<slug:some_title>/', myapp.views.blog_detail, name='blog_detail'),
    ...
]
Run Code Online (Sandbox Code Playgroud)

来源:https : //docs.djangoproject.com/en/2.0/ref/urls/#django.urls.path