Verwenden von {% url ??? %} in Django-Vorlagen

83

Ich habe viel bei Google nach Antworten gesucht, wie das "URL" -Tag in Vorlagen verwendet werden kann, um nur viele Antworten zu finden, die sagen: "Sie fügen es einfach in Ihre Vorlage ein und zeigen auf die Ansicht, für die Sie die URL möchten." Nun, keine Freude für mich :( Ich habe jede mögliche Permutation ausprobiert und als letztes Mittel hier gepostet.

Hier ist es also. Meine urls.py sieht so aus:

from django.conf.urls.defaults import *
from login.views import *
from mainapp.views import *
import settings

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Example:
    # (r'^weclaim/', include('weclaim.foo.urls')),
    (r'^login/', login_view),
    (r'^logout/', logout_view),
    ('^$', main_view),

    # Uncomment the admin/doc line below and add 'django.contrib.admindocs' 
    # to INSTALLED_APPS to enable admin documentation:
    # (r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    (r'^admin/', include(admin.site.urls)),
    #(r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': '/home/arthur/Software/django/weclaim/templates/static'}),
    (r'^static/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),
)

Meine 'views.py' in meinem 'Login'-Verzeichnis sieht folgendermaßen aus:

from django.shortcuts import render_to_response, redirect
from django.template import RequestContext
from django.contrib import auth

def login_view(request):
    if request.method == 'POST':
        uname = request.POST.get('username', '')
        psword = request.POST.get('password', '')
        user = auth.authenticate(username=uname, password=psword)
        # if the user logs in and is active
        if user is not None and user.is_active:
            auth.login(request, user)
            return render_to_response('main/main.html', {}, context_instance=RequestContext(request))
            #return redirect(main_view)
        else:
            return render_to_response('loginpage.html', {'box_width': '402', 'login_failed': '1',}, context_instance=RequestContext(request))
    else:
        return render_to_response('loginpage.html', {'box_width': '400',}, context_instance=RequestContext(request))

def logout_view(request):
    auth.logout(request)
    return render_to_response('loginpage.html', {'box_width': '402', 'logged_out': '1',}, context_instance=RequestContext(request))

und schließlich die main.html, auf die die login_view zeigt:

<html>
<body>
test! <a href="{% url logout_view %}">logout</a>
</body>
</html>

Warum bekomme ich jedes Mal 'NoReverseMatch'?

* (etwas anders musste ich 'context_instance = RequestContext (request)' am Ende aller meiner Render-to-Response-Anwendungen verwenden, da es sonst {{MEDIA_URL}} in meinen Vorlagen nicht erkennen würde und ich nicht referenzieren konnte CSS- oder JS-Dateien. Ich bin mir nicht sicher, warum das so ist. Scheint mir nicht richtig) *

Robert Johnstone
quelle
1
Was Sie über das sagen, context_instance=RequestContext(request)ist richtig. Dies ist erforderlich, um der Vorlage den Zugriff auf die Kontextvariablen zu ermöglichen, die für alle Vorlagen bereitgestellt werden. Dies erfolgt standardmäßig für alle allgemeinen Ansichten, Sie müssen dies jedoch selbst in Ihren benutzerdefinierten Ansichten tun.
Marcus Whybrow
Scheint mir ein bisschen seltsam, weil Sie die ganze Zeit über über Ihre Vorlagen auf Ihre CSS- und JS-Dateien zugreifen werden, um die Konsistenz auf Ihrer Website zu gewährleisten. Sollten Sie daher nicht standardmäßig auf {{MEDIA_URL}} zugreifen können?
Robert Johnstone
1
Die hier akzeptierte Antwort ist nicht mehr gültig
Dan Gayle
Fügen Sie eine neue Antwort hinzu und dann werde ich das akzeptieren
Robert Johnstone

Antworten:

55

Anstatt die logout_viewFunktion zu importieren , sollten Sie eine Zeichenfolge in Ihrer urls.pyDatei angeben:

So nicht (r'^login/', login_view),

aber (r'^login/', 'login.views.login_view'),

Das ist die Standardmethode. Anschließend können Sie auf die URL in Ihren Vorlagen zugreifen, indem Sie:

{% url login.views.login_view %}
Marcus Whybrow
quelle
2
Ja, auf jeden Fall Strings verwenden. Auf diese Weise können Sie auch Präfixe verwenden und müssen nicht alle Ansichtsfunktionen in Ihre URLConf importieren.
Sri Raghavan
Ich habe dies auch versucht und beim Rendern 'CaR NoReverseMatch erwischt: Umgekehrt für' login.views.login_views 'mit Argumenten' () 'und Schlüsselwortargumenten' {} 'nicht gefunden.' wieder :(
Robert Johnstone
Warten Sie ... Kratzen Sie das! Ich wartete 15 Minuten, versuchte es erneut und es funktionierte (yippeeee !!!). Schön 1. Nächste Frage. Wenn ich nur eine Site habe, die ich auf der Admin-Seite hinzugefügt habe, wie kann ich diese an {% url anhängen ??? %}
Robert Johnstone
Ja, das ist ein Nekro, aber das URL-Tag beißt mich 2015 immer noch. Es würde helfen, wenn sie die Syntax nicht ständig ändern würden:
Dave
5
Nur weil ich von Google hierher gekommen bin, sollte ich sagen, dass für Django 1.8+ das Übergeben von Zeichenfolgen als Ansichtsargument veraltet ist und bald entfernt wird. Sie sollten das Callable tatsächlich wie in diesem Beitrag übergeben.
user3599803
103

Die ausgewählte Antwort ist veraltet und keine anderen haben für mich gearbeitet (Django 1.6 und [anscheinend] kein registrierter Namespace.)

Für Django 1.5 und höher (aus den Dokumenten )

Warnung Vergessen Sie nicht, den Funktionspfad oder den Musternamen in Anführungszeichen zu setzen!

Mit einer benannten URL können Sie Folgendes tun:

(r'^login/', login_view, name='login'),
...
<a href="{% url 'login' %}">logout</a>

Genauso einfach, wenn die Ansicht einen anderen Parameter annimmt

def login(request, extra_param):
...
<a href="{% url 'login' 'some_string_containing_relevant_data' %}">login</a>
Mike S.
quelle
1
ja ich weiß. Ich benutze {% load url from future %}im Moment in 1.4. Guter Ort
Robert Johnstone
5
Dies sollte als Antwort ausgewählt werden. Die Verwendung von Zeichenfolgen für URLs mit umgekehrter Übereinstimmung ist in neueren Django-Versionen veraltet.
Sumudu
44

Stellen Sie sicher (Django 1.5 und höher), dass Sie den URL-Namen in Anführungszeichen setzen. Wenn Ihre URL Parameter enthält, sollten diese außerhalb der Anführungszeichen liegen (ich habe Stunden damit verbracht, diesen Fehler herauszufinden!).

{% url 'namespace:view_name' arg1=value1 arg2=value2 as the_url %}
<a href="{{ the_url }}"> link_name </a>
Bogatyr
quelle
Ich weiß, dass dies eine alte Antwort ist, aber das hat mir wirklich geholfen. Ich verwende Django-Norel, eine Abzweigung von Django 1.6, die ebenfalls unter diesem Problem leiden muss, da das Einkapseln des URL-Namens in Anführungszeichen den Typfehler behoben hat, den ich erhalten habe.
Robobrobro
2
Die Verwendung der richtigen Dokumentation hilft ebenfalls, da die Syntax ständig geändert wird: {% url app_views.client client.id %}(keine Anführungszeichen) in 1.4, {% url 'app_views.client' client.id %}(mit Anführungszeichen) in 1.5 -1.7 und {% url 'app-views-client' client.id %}(keine Unterstriche oder Punkte, nur Bindestriche) in 1.8.
Dave
Oh Herr und ich hatten vor, bald auf 1.8 zu aktualisieren.
Bogatyr
17

Das urlTemplate-Tag übergibt den Parameter als Zeichenfolge und nicht als Funktionsreferenz auf reverse(). Der einfachste Weg, dies zum Laufen zu bringen, ist das Hinzufügen von a namezur Ansicht:

url(r'^/logout/' , logout_view, name='logout_view')
Bernhard Vallant
quelle
Ich habe das versucht, aber ich habe 'ungültige Syntax (urls.py, Zeile 14)' :(
Robert Johnstone
Das wirklich Seltsame daran ist, dass ich (PyCharm - nette App) nicht> name = 'logout_view' <wie oben verwenden kann, ohne einen Bibliotheksimport zu empfehlen (libxml2mod.name oder unicodedata.name oder twisted.trial.runner). Name)
Robert Johnstone
Wo ist die Funktion reverse()definiert?
CodyBugstein
In Ihrer Vorlage mit {% url 'logout_view'%} django.readthedocs.org/en/latest/intro/tutorial03.html
Juan Rojas
12

Ich habe das gleiche Problem.

Was ich aus der Dokumentation herausgefunden habe, sollten wir namedspace verwenden.

in deinem Fall {% url login:login_view %}

Eine Liste
quelle
Namespaces werden heutzutage viel häufiger verwendet. Macht URL lesbarer und sie bedeuten Ihnen tatsächlich etwas
Robert Johnstone
Können Sie bitte den Dokumentationslink einfügen?
Geoidesic
1

Nach Ihrem Beispiel zu urteilen, sollte es nicht das {% url myproject.login.views.login_view %}Ende der Geschichte sein? (durch myprojectIhren tatsächlichen Projektnamen ersetzen )

Yuji 'Tomita' Tomita
quelle
Entspricht dem obigen 'CaR NoReverseMatch beim Rendern erwischt: Umkehren für' weclaim.login.views.login_views 'mit Argumenten' () 'und Schlüsselwortargumenten' {} 'nicht gefunden.' (Ich gehe davon aus, dass mein Projektname der gleiche Name ist wie das Stammverzeichnis, in dem mein gesamter Code gespeichert ist)
Robert Johnstone