2014-04-29 18 views
10

Ich habe 2 URLs mit einem Slug-Feld in der URL.Regulärer Ausdruck in URL für Django Slug

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

Der erste öffnet in Ordnung, aber die zweite gibt einen DoesNotExist Fehler sagen Genres matching query does not exist.

Hier ist, wie ich die zweite URL in meinem HTML-bin Zugriff

<li><a href="{% url 'genre_month' slug=genre.slug %}">Monthly Top Songs</a></li> 

Ich versuchte, die Schnecke in der Ansicht zu drucken. Es wird als genre_name/monthly anstelle von genre_name übergeben.

Ich denke, das Problem ist mit der Regex in den URLs. Irgendeine Idee, was hier falsch ist?

Antwort

15

Django verwendet immer das erste Muster, das übereinstimmt. Für URLs, die genres/genre_name/monthly ähneln, stimmt Ihr erstes Muster überein, sodass das zweite Muster niemals verwendet wird. Die Wahrheit ist, dass die Regex nicht spezifisch genug ist und alle Charaktere erlaubt - was keinen Sinn ergibt.

Sie könnten die Reihenfolge jener Muster umkehren, aber was Sie tun sollten, ist, sie präziser zu machen (vgl: urls.py example in generic class-based views docs):

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'), 
+4

Eine Sache zu prüfen, ist eine sinnvolle Begrenzung für die Anzahl der Zeichen mit eher entsprechen als '+' Überlauf-Attacken zu vermeiden, zum Beispiel '(P [- \ w? ] {1,255}) '. Sie können sogar das Minimum auf diese Weise erhöhen, wenn Sie weiter einschränken wollen, was Sie wollen und was nicht. – Tom

10

Ich glaube, dass Sie auch die _ aus dem Muster fallen kann, dass @Ludwik hat auf diese Version vorgeschlagen und überarbeiten (die ein Zeichen einfacher :) ist):

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'), 

Beachten Sie, dass \w steht für "Wortzeichen ". Es entspricht immer den ASCII-Zeichen [A-Za-z0-9_]. Beachten Sie die Aufnahme von Unterstrich und Ziffern. more info

+0

Vielen Dank, Sie haben Recht. Mein Code basierte direkt auf dem Beispiel der Django-Dokumentation, die zuletzt korrigiert wurde (zwischen Version 1.7 und 1.8), und verwendet nun auch die einfachere '- \ w'-Version. Ich werde meine Antwort bearbeiten, um das zu reflektieren. –

+0

Ich bin froh, dass ich dazu beitragen konnte (und sogar durch einen einfachen Charakter). Danke für deine Anerkennung @ludwik :) –