Wie erhalte ich den aktuellen URL-Namen mit Django?

89

Ich muss eine URL dynamisch entsprechend der aktuellen URL erstellen. Die Verwendung des {% url %}Tags ist der einfachste Weg, aber ich benötige den aktuellen URL-Namen, um den neuen dynamisch zu generieren.

Wie kann ich den URL-Namen an die URL-Konfiguration anhängen, die zur aktuellen Ansicht führt?

BEARBEITEN: Ich weiß, dass ich die URL manuell von Hand erstellen kann, get_absolute_urlaber ich möchte sie lieber vermeiden, da sie Teil einer Vorlesung ist und ich nur einen Weg zum Erstellen von URLs demonstrieren möchte.

Die Schüler wissen, wie man es benutzt {% url %}. Sie wissen, dass sie vor einem Problem stehen, wenn sie eine vollständigere URL basierend auf der aktuellen erstellen müssen. Am einfachsten ist es {% url %}, mit einigen Variationen erneut zu verwenden. Da wir url benannt haben, müssen wir wissen, wie wir den Namen der URL erhalten, die die aktuelle Ansicht aufgerufen hat.

BEARBEITEN 2: Ein weiterer Anwendungsfall besteht darin, Teile der Basisvorlage je nach Basisvorlage unterschiedlich anzuzeigen. Es gibt andere Möglichkeiten, dies zu tun (mit CSS und {% block%}, aber manchmal ist es einfach schön, das Tag des Menüeintrags von base.html entfernen zu können, wenn der Viewname mit dem Link übereinstimmt.

e-satis
quelle
6
Ich habe diese Frage immer wieder gefunden, als ich nach einer Möglichkeit gesucht habe, die aktuelle, absolute URL über ein Template-Tag auszugeben. Wenn Sie auch danach suchen, ist es:{{ request.get_full_path }}
Dolph

Antworten:

130

Ich weiß nicht, wie lange diese Funktion bereits Teil von Django ist, aber wie der folgende Artikel zeigt, kann sie in der Ansicht wie folgt erreicht werden:

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

Wenn Sie dies in jeder Vorlage benötigen, kann das Schreiben einer Vorlagenanforderung angebracht sein.

Bearbeiten: NEUES DJANGO-UPDATE ANWENDEN

Nach dem aktuellen Django-Update:

Django 1.10 ( Link )

Der Import aus dem django.core.urlresolversModul ist zugunsten seines neuen Speicherorts veraltet.django.urls

Django 2.0 ( Link )

Das django.core.urlresolversModul wird zugunsten seines neuen Standorts entfernt.django.urls .

Der richtige Weg ist also folgender:

from django.urls import resolve
current_url = resolve(request.path_info).url_name
Lukas Bünger
quelle
Warum? Soweit ich Ihre Frage verstanden habe, war ein wesentlicher Teil davon, wie man erreicht: "Da wir URL benannt haben, müssen wir wissen, wie wir den Namen der URL erhalten, die die aktuelle Ansicht aufgerufen hat." ...
Lukas Bünger
1
Eigentlich war ich an diesem Tag mürrisch und habe deine Antwort völlig willkürlich verworfen. Ich entschuldige mich, denn das ist eigentlich die richtige Antwort. Ich werde es bearbeiten, um es offensichtlicher zu machen.
E-Satis
8
resolve()kann nicht aufgelöst werden, wenn Sie eine Abfragezeichenfolge übergeben und einfach eine 404 auslösen. get_full_path()Gibt den Pfad und die Abfragezeichenfolge zurück. Sie müssen verwenden resolve(request.path_info).
Kann Burak Çilingir
Was ist, wenn nicht die currentURL aufgelöst werden muss, sondern beispielsweise die URL, zu der ein Benutzer umleiten wird? Was ist ein allgemeinerer Weg, um dies zu erreichen? Die Antwort von Conley Owens hat eine Ahnung, aber ich würde das Rad lieber nicht neu erfinden, wenn das Rad bereits in Django unter der Motorhaube existiert.
Hassan Baig
Dies scheint nicht für übersetzbare URLs mit i18n_patterns zu funktionieren
Guival
109

Ab Django 1.5 kann über das Anforderungsobjekt darauf zugegriffen werden

    current_url = request.resolver_match.url_name

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

Bharathwaaj
quelle
Wenn ich dies in einen Kontextprozessor gestellt habe, hat es funktioniert, aber dieser seltsame Fehler wurde in der Konsole AttributeError: 'WSGIRequest' object has no attribute 'resolver_match'
angezeigt
2
Der 'resolver_match' wird dem Anforderungsobjekt erst hinzugefügt, nachdem alle Anforderungs-Middleware aufgerufen wurde. Dann werden die URLs aufgelöst. Sie können also nur ab View Middleware zugreifen. (process_view Funktionen der Middleware). Es ist in den Request-Middleware-Funktionen nicht verfügbar. (process_request Funktionen der Middleware).
Bharathwaaj
.view_nameWenn Sie den Namespace benötigen
27

Für diejenigen, die ihre URL-Muster mit einem Namespace versehen, ist der Namespace-URL-Name der Anforderung möglicherweise von Interesse. In diesem Fall nannte es Django view_namestattdessen.

request.resolver_match.view_name

# return: <namespace>:<url name>
Yeo
quelle
Danke, aber das ist so ziemlich ein Betrug von @ dariusz-niespodzianys früherer Antwort, nicht wahr? stackoverflow.com/a/31931833/1450294
Michael Scheper
5
Wenn Sie keinen Namespace haben, ist Ihr urls.py@ dariusz-niespodziany sofort reverseverfügbar. Wenn Sie jedoch einen Namespace verwenden, kann dieser resolver_match.url_namenicht direkt reverseverwendet werden. Sie müssen den Namespace also selbst anhängen. Anstatt es selbst zu tun, hat Django die .view_nameInitialisierung bereits festgelegt .
Yeo
15

Dies kann erreicht werden über:

    request.resolver_match.url_name

Django> 1,8

niespodd
quelle
4

Klärung der Frage: "Wie erhalten Sie in einer Ansicht den Namen eines URL-Musters, das darauf verweist, vorausgesetzt, es gibt genau ein solches URL-Muster."

Dies kann aus den genannten Gründen wünschenswert sein: Innerhalb der Ansicht möchten wir eine TROCKENE Methode, um eine URL in dieselbe Ansicht zu bringen (wir möchten nicht unseren eigenen URL-Musternamen kennen müssen).

Kurze Antwort: Es ist nicht einfach genug, Ihre Klasse zu unterrichten, aber es könnte eine lustige Sache für Sie sein, in ein oder zwei Stunden zu tun und sich auf GitHub zu übergeben.

Wenn Sie dies wirklich tun wollten, müssten Sie RegexURLResolver in eine Unterklasse unterteilen und die Auflösungsmethode ändern, um das übereinstimmende Muster (von dem Sie den Musternamen erhalten können) anstelle der Paare Ansicht und Schlüsselwort / Wert zurückzugeben. http://code.djangoproject.com/browser/django/trunk/django/core/urlresolvers.py#L142

Sie können dann einen Dekorateur oder eine geeignetere Middleware erstellen, die diese Unterklasse verwendet, um den Musternamen abzurufen und diesen Wert irgendwo in der Anforderung zu speichern, damit Ansichten ihn verwenden können.

Wenn Sie das tatsächlich wollen und auf Probleme stoßen, lassen Sie es mich wissen und ich kann Ihnen wahrscheinlich helfen.

Für Ihre Klasse würde ich sie einfach den Musternamen in der Ansicht oder Vorlage fest codieren lassen. Ich glaube, das ist der akzeptable Weg, dies zu tun.

Update: Je mehr ich darüber nachdenke, desto mehr würde ich davon abhalten, einen URL-Musternamen in einer Ansicht zu erhalten. URL-Muster-Parameter sind ziemlich unabhängig von den Parametern der Ansicht, auf die sie zeigen. Wenn Sie auf eine bestimmte URL verweisen möchten, müssen Sie wissen, wie das URL-Muster funktioniert und nicht nur, wie die Ansicht funktioniert. Wenn Sie wissen möchten, wie das URL-Muster funktioniert, müssen Sie möglicherweise auch den Namen des URL-Musters kennen.

Conley Owens
quelle
1

Ihre Frage ist etwas unklar, aber http://docs.djangoproject.com/en/dev/topics/http/urls/ wird wahrscheinlich eine Erklärung dafür liefern, wonach Sie suchen.

Besonders nützlich, um festzustellen, wie Django Anfragen verarbeitet:

Wenn ein Benutzer eine Seite von Ihrer Django-basierten Site anfordert, ist dies der Algorithmus, dem das System folgt, um zu bestimmen, welcher Python-Code ausgeführt werden soll:

  1. Django bestimmt das zu verwendende Root-URLconf-Modul. Normalerweise ist dies der Wert der Einstellung ROOT_URLCONF. Wenn das eingehende HttpRequest-Objekt jedoch ein Attribut namens urlconf (festgelegt durch Middleware-Anforderungsverarbeitung) hat, wird sein Wert anstelle der Einstellung ROOT_URLCONF verwendet.
  2. Django lädt dieses Python-Modul und sucht nach den variablen URL-Mustern. Dies sollte eine Python-Liste in dem von der Funktion django.conf.urls.defaults.patterns () zurückgegebenen Format sein.
  3. Django durchläuft jedes URL-Muster der Reihe nach und stoppt beim ersten, das der angeforderten URL entspricht.
  4. Sobald einer der regulären Ausdrücke übereinstimmt, importiert Django die angegebene Ansicht und ruft sie auf. Dies ist eine einfache Python-Funktion. Der Ansicht wird eine HttpRequest als erstes Argument und alle im regulären Ausdruck als verbleibende Argumente erfassten Werte übergeben.

Wenn Sie kurz nach dem vollständigen Pfad sind, können Sie Folgendes versuchen:

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

Ich hoffe, das hilft - es zeigt an, wie das URLconf-Modul verwendet wird, und hilft Ihnen hoffentlich dabei, in die richtige Richtung zu weisen.

Mark Mayo
quelle
Danke, aber ich weiß das :-) Ich habe einige Erklärungen hinzugefügt, um Missverständnisse zu vermeiden.
E-Satis
0

Versuche es einfach request.path. Dadurch wird der aktuelle Pfad angefordert.

Abhishek Iyengar
quelle