2014-04-29 8 views
10

Ho 2 URL con un campo di lumaca nell'URL.Espressione regolare nell'URL per slog di Django

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

La prima si apre bene, ma il secondo dà un errore dicendo DoesNotExistGenres matching query does not exist.

Ecco come sto accedendo al 2 ° URL nel mio HTML

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

ho provato a stampare la lumaca nella vista. È passato come genre_name/monthly invece che da genre_name.

Penso che il problema sia con la regex negli URL. Qualche idea di cosa c'è che non va qui?

risposta

15

Django utilizza sempre il primo modello corrispondente. Per gli url simili a genres/genre_name/monthly corrisponde al primo schema, quindi il secondo non viene mai utilizzato. La verità è che la regex non è abbastanza specifica, consentendo a tutti i personaggi - il che non sembra avere senso.

Si potrebbe invertire l'ordine di quei modelli, ma ciò che si dovrebbe fare è quello di renderli più specifici (confrontare: 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

Una cosa da considerare è usare un limite ragionevole al numero di caratteri da abbinare, piuttosto che '+' per evitare attacchi di overflow, ad esempio, '(P [- \ w? ] {1255}) '. Puoi anche aumentare il minimo in questo modo se vuoi limitare ulteriormente ciò che vuoi e non corrisponderà. – Tom

10

Credo che si può anche cadere il _ dal modello che @Ludwik ha suggerito e rivedere a questa versione (che è un carattere più semplice :)):

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

noti che \w sta per "carattere di parola ". Corrisponde sempre ai caratteri ASCII [A-Za-z0-9_]. Notare l'inclusione del trattino basso e delle cifre. more info

+0

Grazie, hai ragione. Il mio codice era basato direttamente sull'esempio della documentazione di Django, che è stata corretta da quest'ultima (tra la versione 1.7 e 1.8), quindi ora usa anche la più semplice versione '- \ w'. Modificherò la mia risposta per riflettere questo. –

+0

Contento di essere stato in grado di contribuire e semplificare (anche con 1 carattere semplice). Grazie per il tuo riconoscimento @ludwik :) –