2012-06-28 16 views
133

Quando leggo il codice django a volte, vedo in alcuni modelli reverse(). Non sono abbastanza sicuro di cosa sia, ma viene usato insieme a HttpResponseRedirect. Come e quando è possibile utilizzare questo reverse()?cosa è reverse() in Django

Sarebbe bello se qualcuno ha dato una risposta con alcuni esempi ...

+2

Dato un modello di URL, Django utilizza url() per scegliere la giusta visione e generare una pagina. Cioè, 'url -> visualizza nome'. Ma a volte, come quando si sta reindirizzando, è necessario andare nella direzione opposta e dare a Django il nome di una vista, e Django genera l'URL appropriato. In altre parole, 'visualizza nome -> url'. Cioè, 'reverse()' (è il contrario della funzione url). Potrebbe sembrare più trasparente chiamarlo 'generateUrlFromViewName' ma è troppo lungo e probabilmente non abbastanza generale: https://docs.djangoproject.com/en/dev/topics/http/urls/#reverse-resolution-of-urls – neuronet

+0

@neuronet Ottima spiegazione, grazie. Questo nome mi sembrava (e sembra) particolarmente non intuitivo per me, che ritengo sia un peccato grave. Chi non odia l'offuscamento non necessario? –

risposta

215

https://docs.djangoproject.com/en/stable/ref/urlresolvers/#reverse

nel vostro urls.py definire questo:

url(r'^foo$', some_view, name='url_name'), 

in un modello è possibile fare riferimento a questo URL come:

<!-- django <= 1.4 --> 
<a href="{% url url_name %}">link which calls some_view</a> 

<!-- django >= 1.5 or with {% load url from future %} in your template --> 
<a href="{% url 'url_name' %}">link which calls some_view</a> 

questo sarà reso come

<a href="/foo/">link which calls some_view</a> 

ora dì che vuoi fare qualcosa di simile nel tuo views.py - ad es. si gestisce qualche altro url (non /foo/) in qualche altro punto di vista (non some_view) e si desidera reindirizzare l'utente a /foo/ (spesso il caso sul successo invio di un modulo)

si può solo fare

return HttpResponseRedirect('/foo/') 

ma se si desidera modificare l'URL in futuro, è necessario aggiornare il proprio urls.pye tutti i riferimenti ad esso nel codice. Questo viola DRY (google it).

invece si può dire

from django.core.urlresolvers import reverse 
return HttpResponseRedirect(reverse('url_name')) 

Questo guarda attraverso tutti gli URL definiti nel progetto per l'URL definito con il nome url_name e restituisce l'URL reale /foo/.

Ciò significa che si fa riferimento all'url solo tramite l'attributo name. Se si desidera modificare l'URL stesso o la vista a cui fa riferimento, è possibile farlo modificando un solo posto - urls.py. L'intera idea di editare un posto solo si riferisce a "Non ripetere te stesso" ed è qualcosa per cui lottare.

+1

FYI, '{{url 'url_name'}}' dovrebbe essere '{% url url_name%}' in Django 1.4 o precedente. Questo cambierà nella prossima versione di Django (1.5) e dovrebbe quindi essere '{% url 'url_name'%}'. I documenti per [url templatetag] (https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#url) forniscono alcune informazioni utili se si scorre verso il basso un po 'nella sezione "compatibilità diretta" –

+0

j_syk grazie - ho fatto @load url dal futuro @ da 1.3 è uscito e ho dimenticato che non è ancora il default. Aggiornerò la mia risposta in modo da non far inciampare l'inesperto. – scytale

+0

non essere troppo critico, e per continuare sul tema di non far inciampare l'inesperto, ma dovrebbe essere tag di blocco '{%%}' tag non variabili '{{}}' per il tag url :) –

0

L'inverso() è utilizzato per aderire al principio django DRY, vale a dire se si modifica l'URL in futuro, quindi è possibile fare riferimento a tale URL utilizzando reverse (urlname).

1

La funzione supporta il principio di asciugatura, assicurando che non si eseguano url di codici rigidi in tutta l'app. Un URL deve essere definito in un unico luogo e solo in un posto: il tuo URL conf. Dopodiché stai solo facendo riferimento a queste informazioni.

Utilizzare reverse() per fornire l'URL di una pagina, dato il percorso della vista o il parametro page_name dall'URL conf. Lo useresti nei casi in cui non ha senso farlo nel modello con {% url 'my-page' %}.

Ci sono molti possibili luoghi in cui è possibile utilizzare questa funzionalità. Un posto ho trovato lo uso è quando reindirizzare gli utenti a una vista (spesso dopo l'elaborazione di successo di un modulo) -

return HttpResponseRedirect(reverse('thanks-we-got-your-form-page'))

Si potrebbe anche utilizzare quando si scrive tag modello.

Un'altra volta che ho utilizzato reverse() era con l'ereditarietà del modello. Ho avuto una ListView su un modello padre, ma volevo ottenere da uno qualsiasi di questi oggetti padre per il DetailView del suo oggetto figlio associato. Ho allegato una funzione get__child_url() al genitore che ha identificato l'esistenza di un bambino e ha restituito l'url della sua DetailView utilizzando reverse().

1

Troppo vecchia questione, ma questo potrebbe aiutare qualcuno

dai documentazione ufficiale

"Django fornisce gli strumenti per l'esecuzione di URL invertire quella partita i diversi strati in cui sono necessari URL: In modelli: utilizzando l'URL tag modello In codice Python: utilizzo della funzione reverse() Nel codice di livello superiore relativo alla gestione degli URL delle istanze del modello Django: il metodo get_absolute_url(). "

esempio: nei modelli (tag url)

<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a> 

Esempio: nel codice python (funzione inversa)

return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))