2011-01-04 7 views
49

Ho cercato molto su google per le risposte su come usare il tag 'url' nei template solo per trovare molte risposte dicendo 'Basta inserirlo nel tuo template e puntarlo alla vista che vuoi url per '. Beh no gioia per me :(Ho provato ogni permutazione possibile e hanno fatto ricorso a distacco qui come ultima risorsaUtilizzo di {% url ??? %} in django templates

Così qui è il mio urls.py assomiglia a questo:..

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

mio ' views.py' nel mio 'directory di login' assomiglia:

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

e infine la main.html a cui punta login_view assomiglia:

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

Quindi perché ottengo "NoReverseMatch" ogni volta?

* (su una nota leggermente diversa ho dovuto usare "context_instance = RequestContext (request)" alla fine di tutti i miei render-to-response perché altrimenti non riconoscerebbe {{MEDIA_URL}} nei miei template e io non posso fare riferimento a nessun file css o js. *

+1

Quello che dici del 'context_instance = RequestContext (request)' è corretto, questo è necessario per consentire al modello di accedere alle variabili di contesto fornite a tutti i template. Questo è fatto di default per tutte le viste generiche, ma devi farlo tu stesso in quelle personalizzate. –

+0

Sembra un po 'strano per me perché accederai ai tuoi file css e js tutto il tempo dai tuoi modelli per mantenere la coerenza sul tuo sito. Pertanto, non dovresti poter accedere a {{MEDIA_URL}} per impostazione predefinita? – Sevenearths

+0

La risposta accettata qui non è più valida –

risposta

39

Invece di importare la funzione logout_view, è necessario fornire una stringa nel file urls.py:

Quindi non (r'^login/', login_view),

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

Questo è il modo standard di fare le cose. Quindi è possibile accedere all'URL nei template utilizzando:

{% url login.views.login_view %} 
+2

sì, sicuramente uso le stringhe. in questo modo, puoi anche usare i prefissi e non devi importare tutte le funzioni di visualizzazione nel tuo URLConf. –

+0

Ho provato anche questo e ho ottenuto 'Caught NoReverseMatch durante il rendering: Reverse per' login.views.login_views 'con gli argomenti'() 'e gli argomenti delle parole chiave' {} 'non trovati.' ancora :( – Sevenearths

+0

Aspetta ... Scratch that! Ho aspettato 15 minuti, ho provato di nuovo e ha funzionato (yippeeee !!!). Bello 1. Domanda successiva.Se ho solo un sito che ho aggiunto nella pagina di amministrazione, come posso suffix this a {% url ???%} – Sevenearths

16

Il tag modello url passerà il parametro come una stringa e non come una funzione di riferimento per reverse(). Il modo più semplice per ottenere questo lavoro è l'aggiunta di un name alla vista:

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

Ho provato che ma ho "sintassi non valida (urls.py, riga 14)" :( – Sevenearths

+0

ciò che è veramente strano in questo è che (PyCharm - app bella) non mi permette di usare> name = 'logout_view' Sevenearths

+0

Dove è definita la funzione 'reverse()'? – CodyBugstein

1

A giudicare dal tuo esempio, non dovrebbe che si tratti {% url myproject.login.views.login_view %} e la fine della storia? (sostituisci myproject con il nome del tuo vero progetto)

+0

Come sopra 'Caught NoReverseMatch durante il rendering: Inverti per 'weclaim.login.views.login_views' con argomenti '()' e argomenti di parole chiave '{}' non trovati. ' (Presumo che il nome del mio progetto sia lo stesso della directory radice in cui è memorizzato tutto il mio codice) – Sevenearths

8

Mi imbatto nello stesso problema.

Quello che ho trovato dalla documentazione, dovremmo usare namedspace.

nel tuo caso {% url login:login_view %}

+0

Utilizzo di namespace molto più ora al giorno. Rende l'URL più leggibile e in realtà significa qualcosa per te – Sevenearths

57

La risposta selezionata è di vecchia data e nessun altro ha lavorato per me (Django 1.6 e [apparantly] senza namespace registrato.)

Per Django 1.5 e versioni successive (da the docs)

Attenzione non dimenticare di mettere le virgolette attorno al percorso della funzione o il nome del modello!

con un URL di nome che si possa fare:

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

Altrettanto facile se la vista abbraccia un altro parametro

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

sì, lo so. Sto usando '{% carica url dal futuro%}' in 1.4 al momento. Good spot – Sevenearths

+2

Questo dovrebbe essere selezionato come risposta. L'utilizzo di stringhe per gli URL di corrispondenza inversa è deprecato nelle nuove versioni di django. – Anubis

25

Assicurarsi (Django 1.5 e oltre) che si mette l'url nome tra virgolette, e se il tuo url prende parametri dovrebbero essere al di fuori di le virgolette (ho passato ore a capire questo errore!).

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

So che questa è una vecchia risposta, ma questo mi ha davvero aiutato. Sto usando django-norel, che è un fork di Django 1.6, che deve anche soffrire di questo problema perché incapsulare il nome dell'URL tra virgolette ha risolto l'errore TypeError che stavo ottenendo. – robobrobro

+1

Anche l'utilizzo della documentazione corretta aiuta, poiché continuano a cambiare la sintassi: '{% url app_views.client client.id%}' (senza virgolette) in 1.4, '{% url 'app_views.client' client.id%}' (con virgolette) in 1.5 -1.7 e '{% url 'app-views-client' client.id%}' (senza trattini bassi o punti, solo trattini) in 1.8. – Dave

+0

Oh Lord e io stavamo programmando di aggiornare presto a 1.8. – Bogatyr