it-swarm.com.ru

Используя {% url ??? %} в шаблонах Django

Я много раз искал в Google ответы о том, как использовать тег 'url' в шаблонах, только чтобы найти множество ответов, говорящих: "Просто вставьте его в свой шаблон и наведите на представление, для которого вы хотите получить URL". Ну, нет радости для меня :( Я перепробовал каждую возможную перестановку и прибегнул к публикации здесь в качестве последнего средства.

Так и здесь. Мой urls.py выглядит так:

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

Мой 'views.py' в моем каталоге 'login' выглядит так:

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

и, наконец, main.html, на который указывает login_view:

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

Так почему я получаю 'NoReverseMatch' каждый раз?

* (на несколько другой ноте я должен был использовать "context_instance = RequestContext (request)" в конце всех моих обработок рендеринга к ответу, потому что в противном случае он не распознавал бы {{MEDIA_URL}} в моих шаблонах, и я не мог ссылаться любые файлы CSS или JS. Я не уверен, почему это так. Мне не кажется правильным) *

63
Sevenearths

Вместо того, чтобы импортировать функцию logout_view, вы должны предоставить строку в вашем файле urls.py:

Так что не (r'^login/', login_view),

но (r'^login/', 'login.views.login_view'),

Это стандартный способ ведения дел. Затем вы можете получить доступ к URL в ваших шаблонах, используя:

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

Выбранный ответ устарел, и другие не работали для меня (Django 1.6 и [явно] нет зарегистрированного пространства имен.)

Для Django 1.5 и более поздних версий (из документы )

Предупреждение Не забудьте поставить кавычки вокруг пути функции или имени шаблона!

С именованным URL вы можете сделать:

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

Так же просто, если представление принимает другой параметр

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

Убедитесь (в Django 1.5 и более поздних версиях), что вы вводите имя URL в кавычках, и если ваш URL принимает параметры, они должны быть вне кавычек (я часами разбирался с этой ошибкой!).

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

Тег шаблона url будет передавать параметр в виде строки, а не в виде ссылки на функцию в reverse(). Самый простой способ добиться этого - добавить name в представление:

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

Я сталкиваюсь с той же проблемой.

Что я нашел из документации, мы должны использовать пространство имен.

в вашем случае {% url login:login_view %}

12
Alist

Судя по вашему примеру, разве это не должен быть {% url myproject.login.views.login_view %} и конец истории? (замените myproject вашим реальным именем проекта)

1
Yuji 'Tomita' Tomita