web-dev-qa-db-fra.com

Utilisation de {% url ??? %} in Django templates

J'ai beaucoup cherché sur Google pour savoir comment utiliser la balise "url" dans les modèles, puis trouver de nombreuses réponses disant "Vous l'insérez simplement dans votre modèle et pointez-le sur la vue pour laquelle vous voulez que l'URL soit". Eh bien, pas de joie pour moi :( J'ai essayé toutes les permutations possibles et ai posté ici en dernier recours.

Alors le voici. 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" se présente comme suit:

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 auquel les points login_view ressemblent:

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

Alors, pourquoi ai-je "NoReverseMatch" à chaque fois?

* (sur une note légèrement différente, je devais utiliser 'context_instance = RequestContext (request)' à la fin de tous mes rendus de réponse car sinon, il ne reconnaîtrait pas {{MEDIA_URL}} dans mes modèles et je ne pourrais pas faire référence à tous les fichiers css ou js. Je ne suis pas sûr de savoir pourquoi. Cela ne me semble pas juste) *

68
Sevenearths

Au lieu d'importer le logout_view fonction, vous devez fournir une chaîne dans votre urls.py fichier:

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

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

C'est la manière habituelle de faire les choses. Ensuite, vous pouvez accéder à l'URL dans vos modèles en utilisant:

{% url login.views.login_view %}
47
Marcus Whybrow

La réponse sélectionnée est obsolète et aucune autre solution ne fonctionnait pour moi (Django 1.6 et [apparemment] aucun espace de nom enregistré.)

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

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

Avec une URL nommée, vous pouvez faire:

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

Tout aussi facile si la vue prend un autre paramètre

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

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

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

La balise de modèle url transmettra le paramètre en tant que chaîne et non en tant que référence de fonction à reverse(). Le moyen le plus simple de faire fonctionner cela consiste à ajouter un name à la vue:

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

Je rencontre le même problème.

Ce que j'ai trouvé dans la documentation, nous devrions utiliser namedspace.

dans ton cas {% url login:login_view %}

12
Alist

À en juger par votre exemple, cela ne devrait-il pas être {% url myproject.login.views.login_view %} et fin de l'histoire? (remplacez myproject par votre nom de projet actuel)

1