2011-01-04 1 views
49

Я много искал в Google для ответов на вопрос о том, как использовать тег 'url' в шаблонах, чтобы найти много ответов, говорящих: «Вы просто вставляете его в свой шаблон и указываете на вид, который хотите url для '. Ну не радость для меня :(Я попробовал все перестановки можно и прибегли к публикации здесь в качестве последнего средстваИспользование {% url ??? %} в шаблонах django

Так вот мой 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»в моем 'домашнем каталоге' выглядит следующим образом:

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. Я не уверен, почему это так. Не кажется мне правильным) *

+1

Что вы говорите о 'context_instance = RequestContext (request)' правильно, это необходимо, чтобы позволить шаблону получить доступ к переменным контекста, предоставленным всем шаблонам. Это делается по умолчанию для всех общих представлений, но вам нужно сделать это самостоятельно в своих пользовательских. –

+0

Кажется немного странным для меня, потому что вы собираетесь получать доступ к своим css и js-файлам все время из ваших шаблонов, чтобы поддерживать последовательность на вашем сайте. Следовательно, вы не должны иметь доступ к {{MEDIA_URL}} по умолчанию? – Sevenearths

+0

Принимаемый ответ здесь больше не действителен –

ответ

39

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

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

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

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

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

да, определенно используйте строки. таким образом, вы также можете использовать префиксы, и вам не нужно импортировать все ваши функции просмотра в ваш URLConf. –

+0

Я тоже это пробовал и получил «Пойманный NoReverseMatch при рендеринге: Реверс для« login.views.login_views »с аргументами«() »и аргументами ключевого слова« {} «не найден». снова :( – Sevenearths

+0

Подождите ... Поцарапайте это! Я ждал 15 минут, попробовал еще раз, и это сработало (yippeeee !!!). Nice 1. Следующий вопрос. Если у меня есть только один сайт, который я добавил на странице администратора, как я могу суффиктировать это до {% url ???%} – Sevenearths

16

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

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

Я пробовал но я получил «недействительный синтаксис (urls.py, строка 14)» :( – Sevenearths

+0

что действительно странно в том, что он (PyCharm - приятное приложение) не позволит мне использовать> name = 'logout_view' <как указано выше с рекомендацией библиотечный импорт (libxml2mod.name или unicodedata.name o r twisted.trial.runner.name) – Sevenearths

+0

Где определена функция 'reverse()'? – CodyBugstein

1

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

+0

То же, что и выше« Caught NoReverseMatch while render: Reverse для 'weclaim.login.views.login_views' с аргументами '()' и аргументами ключевого слова '{}' не найден. ' (Я предполагаю, что имя моего проекта совпадает с именем корневого каталога, в котором хранится весь мой код) – Sevenearths

8

Я столкнулся с той же проблемой.

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

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

+0

Использование пространств имен намного больше сейчас. Делает URL более читаемым, и они на самом деле что-то значит для вас – Sevenearths

57

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

Для Django 1.5 и выше (от the docs)

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

С именем 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> 
+1

да, я знаю. Я использую '{% load url from future%}' в 1.4 на данный момент. Хорошее место – Sevenearths

+2

Это должно быть выбрано в качестве ответа. Использование строк для обратных ссылок URL устарело в новых версиях django. – Anubis

25

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

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

Я знаю, что это старый ответ, но это действительно помогло мне. Я использую django-norel, который является вилкой Django 1.6, который также должен переносить эту проблему, поскольку инкапсуляция имени URL-адреса в кавычках исправила TypeError, который я получал. – robobrobro

+1

Использование правильной документации также помогает, так как они продолжают изменять синтаксис: '{% url app_views.client client.id%}' (без кавычек) в 1.4, '{% url 'app_views.client' client.id%}' (с кавычками) в 1,5 -1,7 и '{% url 'app-views-client' client.id%}' (без подчеркиваний или точек, просто тире) в 1.8. – Dave

+0

О, мы с Богом планировали скоро перейти на 1.8. – Bogatyr