Come ottenere il nome dell'URL corrente utilizzando Django?


90

Devo creare dinamicamente un URL in base all'URL corrente. L'uso del {% url %}tag è il modo più semplice per farlo, ma ho bisogno del nome dell'URL corrente per generare dinamicamente quello nuovo.

Come posso ottenere il nome dell'URL allegato all'urlconf che porta alla visualizzazione corrente?

EDIT: So che posso creare manualmente l'URL usando get_absolute_urlma preferirei evitarlo poiché fa parte di una lezione e vorrei dimostrare solo un modo per creare URL.

Gli studenti sanno come usare {% url %}. Sanno di fronte a un problema quando devono generare un URL più completo basato su quello corrente. Il modo più semplice è {% url %}riutilizzarlo, con alcune variazioni. Dato che abbiamo chiamato url, dobbiamo sapere come ottenere il nome dell'url che ha chiamato la visualizzazione corrente.

MODIFICA 2: un altro caso d'uso è visualizzare parti del modello di base in modo diverso a seconda del modello di base. Ci sono altri modi per farlo (usando CSS e {% block%}, ma a volte è semplicemente bello poter rimuovere il tag della voce di menu di base.html se il nome della vista corrisponde al collegamento.


6
Ho continuato a trovare questa domanda mentre cercavo un modo per visualizzare l' URL attuale e assoluto tramite un tag modello ... se stai cercando anche quello, è:{{ request.get_full_path }}
Dolph

Risposte:


134

Non so da quanto tempo questa funzione faccia parte di Django ma, come mostra il seguente articolo , può essere ottenuta come segue nella vista:

   from django.core.urlresolvers import resolve
   current_url = resolve(request.path_info).url_name

Se ne hai bisogno in ogni modello, può essere appropriato scrivere una richiesta di modello.

Modifica: APPLICAZIONE DEL NUOVO AGGIORNAMENTO DI DJANGO

Dopo l'attuale aggiornamento di Django:

Django 1.10 ( collegamento )

L'importazione dal django.core.urlresolversmodulo è deprecata a favore della sua nuova posizione,django.urls

Django 2.0 ( collegamento )

Il django.core.urlresolversmodulo viene rimosso a favore della sua nuova posizione, django.urls.

Quindi, il modo giusto per farlo è così:

from django.urls import resolve
current_url = resolve(request.path_info).url_name

Perché? Per quanto ho capito la tua domanda, una parte vitale era come ottenere "Dato che abbiamo chiamato url, dobbiamo sapere come ottenere il nome dell'URL che ha chiamato la vista corrente." ...
Lukas Bünger

1
In realtà lukas ero scontroso quel giorno e ho scartato la tua risposta in modo completamente arbitrario. Mi scuso, perché questa è effettivamente la risposta giusta. lo modificherò per renderlo più ovvio.
e-satis

8
resolve()non può essere risolto se gli si passa una stringa di query e si solleva semplicemente un 404. get_full_path()restituisce il percorso e la stringa di query. Avrai bisogno di usare resolve(request.path_info).
Can Burak Çilingir

E se non fosse l' currentURL che deve essere risolto, ma, diciamo, quello a cui un utente reindirizzerà? Qual è un modo più generico per ottenere questo risultato? La risposta di Conley Owens ha un indizio, ma preferirei non reinventare la ruota se detta ruota esiste già a Django sotto il cofano.
Hassan Baig

Questo non sembra funzionare per gli URL traducibili con i18n_patterns
guival

109

A partire da Django 1.5, è possibile accedervi dall'oggetto richiesta

    current_url = request.resolver_match.url_name

https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.resolver_match


Quando l'ho inserito in un processore di contesto ha funzionato, ma questo strano errore è stato mostrato nella console:AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
fjsj

2
Il "resolver_match" viene aggiunto all'oggetto richiesta solo dopo aver chiamato tutto il middleware delle richieste. È allora che gli URL vengono risolti. Quindi puoi accedere solo dal middleware di visualizzazione in poi. (funzioni process_view del middleware). Non sarà disponibile nelle funzioni middleware di richiesta. (funzioni process_request del middleware).
Bharathwaaj

.view_namese hai bisogno dello spazio dei nomi

27

Per coloro che utilizzano lo spazio dei nomi per i pattern URL, potrebbe interessarti il ​​nome dell'URL con spazio dei nomi della richiesta. In questo caso, Django l'ha chiamato view_nameinvece.

request.resolver_match.view_name

# return: <namespace>:<url name>

Grazie, ma questo è praticamente un duplicato della risposta precedente di @ dariusz-niespodziany, non è vero? stackoverflow.com/a/31931833/1450294
Michael Scheper

5
Se non hai lo spazio dei nomi, il tuo urls.py@ dariusz-niespodziany è immediatamente reversedisponibile. Ma se stai usando lo spazio dei nomi, resolver_match.url_namenon è direttamente reverse-able. Quindi devi aggiungere lo spazio dei nomi da solo. Quindi, invece di farlo da solo, Django ha già impostato l' .view_nameinizializzazione.
Yeo

15

Ciò può essere ottenuto tramite:

    request.resolver_match.url_name

Django> 1.8


4

Chiarimento della domanda: "In una vista, come si ottiene il nome di un urlpattern che punta ad esso, supponendo che esista esattamente uno di questi urlpattern."

Questo può essere desiderabile per i motivi indicati: dall'interno della vista, vogliamo un modo DRY per ottenere un URL nella stessa vista (non vogliamo dover conoscere il nostro nome urlpattern).

Risposta breve: non è abbastanza semplice insegnare alla tua classe, ma potrebbe essere una cosa divertente da fare in un'ora o due e vomitare su GitHub.

Se lo desideri davvero, dovresti sottoclassare RegexURLResolver e modificare il metodo di risoluzione per restituire il modello corrispondente (da cui puoi ottenere il nome del modello) invece della vista e delle coppie parola chiave / valore. http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

È quindi possibile creare un decoratore o forse un middleware più appropriato che utilizza questa sottoclasse per ottenere il nome del modello e memorizzare quel valore da qualche parte nella richiesta in modo che le viste possano usarlo.

Se davvero vuoi farlo e incontri dei problemi, fammelo sapere e probabilmente posso aiutarti.

Per la tua classe, vorrei semplicemente codificare il nome del pattern nella vista o nel modello. Credo che questo sia il modo accettabile per farlo.

Aggiornamento: più ci penso, più scoraggerei il tentativo di ottenere un nome urlpattern in una vista. I parametri urlpattern sono abbastanza indipendenti dai parametri della vista a cui puntano. Se vuoi puntare a un certo URL, devi sapere come funziona urlpattern, non solo come funziona la vista. Se hai bisogno di sapere come funziona urlpattern, potresti anche dover conoscere il nome di urlpattern.




1

È un po 'poco chiaro dalla tua domanda, ma http://docs.djangoproject.com/en/dev/topics/http/urls/ probabilmente fornirà una spiegazione a ciò che stai cercando.

Particolarmente utile per notare come Django elabora le richieste:

Quando un utente richiede una pagina dal tuo sito basato su Django, questo è l'algoritmo che il sistema segue per determinare quale codice Python eseguire:

  1. Django determina il modulo URLconf di root da utilizzare. Normalmente, questo è il valore dell'impostazione ROOT_URLCONF, ma se l'oggetto HttpRequest in entrata ha un attributo chiamato urlconf (impostato dall'elaborazione della richiesta middleware), il suo valore verrà utilizzato al posto dell'impostazione ROOT_URLCONF.
  2. Django carica quel modulo Python e cerca la variabile urlpatterns. Dovrebbe essere un elenco Python, nel formato restituito dalla funzione django.conf.urls.defaults.patterns ().
  3. Django scorre ogni pattern URL, in ordine, e si ferma al primo che corrisponde all'URL richiesto.
  4. Una volta che una delle espressioni regolari corrisponde, Django importa e chiama la vista data, che è una semplice funzione Python. Alla visualizzazione viene passato un HttpRequest come primo argomento e tutti i valori acquisiti nella regex come argomenti rimanenti.

Se sei subito dopo il percorso completo, puoi provare:

http://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.get_full_path

Spero che sia d'aiuto: indica come utilizzare il modulo URLconf e, si spera, ti aiuterà ad indirizzarti nella giusta direzione.


Grazie ma lo so :-) Ho aggiunto alcune spiegazioni per evitare malintesi.
e-satis
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.