Dużo szukałem w Google w poszukiwaniu odpowiedzi, jak używać tagu „url” w szablonach tylko po to, aby znaleźć wiele odpowiedzi mówiących „Po prostu wstaw go do szablonu i skieruj na widok, dla którego chcesz uzyskać adres URL”. Cóż, nie ma dla mnie radości :( Próbowałem wszystkich możliwych kombinacji i uciekłem się do publikowania tutaj w ostateczności.
Więc oto jest. Mój adres urls.py wygląda następująco:
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}),
)
Mój „views.py” w moim katalogu „login” wygląda następująco:
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))
i na końcu main.html, do którego wygląda punkt login_view:
<html>
<body>
test! <a href="{% url logout_view %}">logout</a>
</body>
</html>
Dlaczego więc za każdym razem otrzymuję „NoReverseMatch”?
* (nieco inaczej musiałem użyć „context_instance = RequestContext (request)” na końcu wszystkich moich renderowań do odpowiedzi, ponieważ w przeciwnym razie nie rozpoznałbym {{MEDIA_URL}} w moich szablonach i nie mogłem się odwołać żadnych plików css lub js. Nie wiem, dlaczego tak jest. Nie wydaje mi się to właściwe) *
źródło
context_instance=RequestContext(request)
jest poprawne, jest to konieczne, aby umożliwić szablonowi dostęp do zmiennych kontekstowych dostarczonych do wszystkich szablonów. Odbywa się to domyślnie dla wszystkich widoków ogólnych, ale w niestandardowych widokach musisz to zrobić samodzielnie.Odpowiedzi:
Zamiast importować
logout_view
funkcję, powinieneś podać ciąg w swoimurls.py
pliku:Zatem nie
(r'^login/', login_view),
ale
(r'^login/', 'login.views.login_view'),
To jest standardowy sposób robienia rzeczy. Następnie możesz uzyskać dostęp do adresu URL w swoich szablonach za pomocą:
źródło
Wybrana odpowiedź jest nieaktualna i żadna inna nie działała dla mnie (Django 1.6 i [najwyraźniej] brak zarejestrowanej przestrzeni nazw).
Dla Django 1.5 i nowszych (z dokumentacji )
Dzięki nazwanemu adresowi URL możesz:
(r'^login/', login_view, name='login'), ... <a href="{% url 'login' %}">logout</a>
Równie łatwe, jeśli widok przyjmuje inny parametr
def login(request, extra_param): ... <a href="{% url 'login' 'some_string_containing_relevant_data' %}">login</a>
źródło
{% load url from future %}
W tej chwili używam wersji 1.4. Dobre miejsceUpewnij się (django 1.5 i nowsze), że umieściłeś nazwę adresu URL w cudzysłowie, a jeśli twój adres URL przyjmuje parametry, powinny one znajdować się poza cudzysłowami (spędziłem godziny na zastanawianiu się nad tym błędem!).
{% url 'namespace:view_name' arg1=value1 arg2=value2 as the_url %} <a href="{{ the_url }}"> link_name </a>
źródło
{% url app_views.client client.id %}
(bez cudzysłowów) w 1.4,{% url 'app_views.client' client.id %}
(z cudzysłowami) w 1.5-1.7 i{% url 'app-views-client' client.id %}
(bez podkreślenia i kropek, tylko myślniki) w 1.8.url
Szablon minie parametr jako ciąg znaków, a nie jako odniesienie do funkcjireverse()
. Najprostszym sposobem, aby to działało, jest dodaniename
do widoku:url(r'^/logout/' , logout_view, name='logout_view')
źródło
reverse()
zdefiniowana funkcja ?Mam ten sam problem.
To, co znalazłem z dokumentacji, powinniśmy użyć namedspace.
w Twoim przypadku
{% url login:login_view %}
źródło
Sądząc po twoim przykładzie, czy nie powinno to być
{% url myproject.login.views.login_view %}
i koniec historii? (zastąpmyproject
rzeczywistą nazwą projektu)źródło