2015-09-04 6 views
6

Fino ad ora un compagno di squadra usato questo codice per i modelli di URL di nomi utente:Django: urlpattern per username?

# urls.py 
urlpatterns = patterns('...', 
    url(r'^user/(?P<username>[.-_\w]+)/foo', 'myapp.views.foo'), 
    .... 

c'è un bug nascosto: Se il nome utente contiene un - l'inversione fallirebbe, fin dall'inizio del pattern regex [.-_ significa "tutti i caratteri da . a _".

Quale motivo può essere utilizzato per corrispondere a tutti i nomi utente validi?

PS: Suppongo che aggiungere il segno - alla regex non sia sufficiente, se si desidera abbinare tutti i nomi utente possibili in django.

risposta

5

Non credo che si dovrebbe mettere alcuna convalida nome utente nel vostro modello di URL. Mantieni la convalida in un unico posto: il luogo in cui crei i tuoi account per la prima volta.

È corrispondere a qualsiasi elemento fornito dall'utente e passare a una funzione di database sicura per cercare il nome utente e fallire se non esiste.

Quindi, nel tuo modello URL, lascia che il browser invii tutto ciò che non è vuoto e fai affidamento sul tuo database molto intelligente per dirti che cosa hai deciso in precedenza era valido o meno.

url(r'^user/(?P<username>.+)/foo$', 'myapp.views.foo'), 

Inoltre, notare "$" alla fine.

4

È possibile spostare il trattino per l'inizio della classe di caratteri,

[-.\w] 

o si può sfuggire con un backslash

[.\-\w] 

Nota Ho rimosso la sottolineatura, dal momento che è incluso in \w. Suppongo anche che tu voglia accettare solo ., - e \w e che tu non voglia accettare tutti i caratteri da . a _. Questa gamma include caratteri come @, quindi potresti voler controllare che tutti i tuoi nomi utente corrispondano alla nuova espressione regolare.

7

Sulla base di quello che vedo nel modello AbstractUser, penso che una regex migliore da utilizzare per afferrare il nome utente sia (?P<username>[\[email protected]+-]+).

+0

Grazie per questa risposta. Le altre risposte mi dicono come includere un trattino nella regex. Non è di questo che si tratta. Si tratta di abbinare qualsiasi nome utente valido. – guettli

0

Prima di tutto, non è un bug ma una caratteristica well documented in the docs:

[]

Utilizzato per indicare un insieme di caratteri. In un set:

Gli intervalli di caratteri possono essere indicati dando due caratteri e separandoli con un '-', ad esempio [az] corrisponderà a qualsiasi lettera ASCII minuscola, [0-5] [0-9] sarà abbinare tutti i numeri a due cifre da 00 a 59 e [0-9A-Fa-f] corrisponderà a qualsiasi cifra esadecimale. Se - è sfuggito (ad esempio [a-z]) o se è collocato come primo o ultimo carattere (ad es. [A-]), corrisponderà a un valore letterale '-'.

Quindi, utilizzando - tra due letterali valuterà che regex come un intervallo di caratteri:

re.compile("[a-0]+") 
>> error: bad character range 
re.findall("[.-_]+", "asdasd-asdasdad._?asdasd-") 
>> ['._?'] 

Come si vede, pitone sarà sempre interperet - come un indicatore serie se usato tra i caratteri del set di caratteri.

Come è (anche) ha dichiarato nei documenti, evitando una dichiarazione gamma è fatto da sfuggire al - con \- o ponendolo come il primo o l'ultimo letterale il set di caratteri []

Se si desidera catturare quel intervallo di caratteri tra cui -, quindi provare:

re.findall("[.-_\-]+", "asdasd-asdasdad._?asdasd-") 
>> ['-', '._?', '-'] 

Nota:\w è uguale a [a-zA-Z0-9_] quando LOCALE e UNICODE flag non sono impostati. Quindi non è necessario dichiarare _ nuovo

E per l'utente:

url(r'^user/(?P<username>[-.\w]+)/foo', 'myapp.views.foo') 
url(r'^user/(?P<username>[.\w-]+)/foo', 'myapp.views.foo') 
url(r'^user/(?P<username>[.\-\w]+)/foo', 'myapp.views.foo') 

oltre l'uso -, se si utilizza di default Django Nome utente styling, quindi @ navneet35371 è di destra circa il set di caratteri validi. Si può modificare il vostro personaggio regex impostato per includere @ e + e utilizzare

url(r'^user/(?P<username>[\[email protected]+-]+)/foo', 'myapp.views.foo') 
3

È possibile utilizzare seguente modo:

[-.\w] (- uso in più a sinistra)

o[.\-\w] (- utilizzare con barra rovesciata in qualsiasi luogo)

o[.\w-] (- uso in più a destra)

se si utilizzano caratteri speciali poi miglior uso\ (backslash) prima di qualsiasi caratteri speciali (che vengono utilizzati in carattere speciale regex.).

Per un utilizzo ottimale la vostra regex sarà ^user/(?P<username>[.\-_\w]+)/foo