101 votes

Utilisation de {% url ? ?? %} dans les modèles django

J'ai beaucoup cherché sur google des réponses sur l'utilisation de la balise 'url' dans les templates et j'ai trouvé beaucoup de réponses disant 'Il suffit de l'insérer dans votre template et de la pointer sur la vue pour laquelle vous voulez l'url'. Je n'ai pas eu de chance :( J'ai essayé toutes les permutations possibles et je me suis résolu à poster ici en dernier recours.

Le voici donc. Mon urls.py ressemble à ceci :

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}),
)

Mon 'views.py' dans mon répertoire 'login' ressemble à ceci :

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))

et enfin le fichier main.html vers lequel pointe le login_view ressemble à ceci :

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

Alors pourquoi est-ce que j'obtiens à chaque fois "NoReverseMatch" ?

*(Sur une note légèrement différente, j'ai dû utiliser 'context_instance=RequestContext(request)' à la fin de tous mes render-to-response parce que sinon il ne reconnaissait pas {{ MEDIA_URL }} dans mes templates et je ne pouvais pas référencer de fichiers css ou js. Je ne sais pas trop pourquoi. Cela ne me semble pas correct)*

117voto

Mike S Points 104

La réponse sélectionnée est périmée et aucune autre n'a fonctionné pour moi (Django 1.6 et [apparemment] pas d'espace de noms enregistré).

Pour Django 1.5 et les versions ultérieures (à partir de les docs )

Avertissement N'oubliez pas de mettre des guillemets autour du chemin de la fonction ou du nom du modèle !

Avec une URL nommée, vous pouvez le faire :

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

C'est tout aussi simple si la vue prend un autre paramètre

def login(request, extra_param):
...
<a href="{% url 'login' 'some_string_containing_relevant_data' %}">login</a>

61voto

Marcus Whybrow Points 8427

Au lieu d'importer le logout_view vous devez fournir une chaîne de caractères dans votre urls.py fichier :

Donc pas (r'^login/', login_view),

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

C'est la façon habituelle de procéder. Vous pouvez ensuite accéder à l'URL dans vos modèles en utilisant :

{% url login.views.login_view %}

49voto

Bogatyr Points 12027

Assurez-vous (django 1.5 et au-delà) que vous mettez le nom de l'url entre guillemets, et si votre url prend des paramètres, ils doivent être en dehors de les guillemets (j'ai passé des heures à trouver cette erreur !).

{% url 'namespace:view_name' arg1=value1 arg2=value2 as the_url %}
<a href="{{ the_url }}"> link_name </a>

17voto

Bernhard Vallant Points 18035

En url transmettra le paramètre sous la forme d'une chaîne de caractères et non d'une référence de fonction à la balise reverse() . La manière la plus simple de faire fonctionner ce système est d'ajouter un fichier name à la vue :

url(r'^/logout/' , logout_view, name='logout_view')

12voto

Alist Points 169

Je rencontre le même problème.

Ce que j'ai trouvé dans la documentation, c'est qu'il faut utiliser namedspace.

dans votre cas {% url login:login_view %}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X