Ошибка URL-адреса Django в шаблоне с представлением password_change

Я использую Django 1.2.3-3+squeeze1 с сжатием Debian.

Я пытаюсь использовать представление смены пароля Django в своем приложении, соответствующем django.contrib.auth.views.password_change. Похоже, это должно быть просто, но у меня были проблемы.

Для простоты и полноты я укажу на свои файлы приложений онлайн. Приложение называется bixfile. Соответствующий проект Django — bixproj.

Соответствующая строка в url.py: https://bitbucket.org/faheem/bixfile/src/49bcbab3a7be/urls.py#cl-65, а именно

url(r'^password_change/$', 'django.contrib.auth.views.password_change', {'post_change_redirect':reverse('top_folders')}, name="password_change"),

Это ломает любой шаблон, в котором он используется. В настоящее время я использую его только в строке https://bitbucket.org/faheem/bixfile/src/71de33d01f43/templates/calgb_base.html#cl-21 шаблона calgb_base.html, который включен в группу шаблонов, включая представление индекса верхнего уровня, соответствующее шаблон https://bitbucket.org/faheem/bixfile/src/71de33d01f43/templates/index.html. Строка в calgb_base.html

<li><a class="side" href="{% url password_change %}">Password Change</a></li>

Когда я перехожу к верхнему index виду, соответствующему https://bitbucket.org/faheem/bixfile/src/71de33d01f43/urls.py#cl-16 и https://bitbucket.org/faheem/bixfile/src/71de33d01f43/views.py#cl-203 Я вижу ошибку, начиная с

Caught NoReverseMatch while rendering: Reverse for 'password_change'
with arguments '()' and keyword arguments '{}' not found.

Я сомневаюсь, что полная трассировка полезна, но я вставил ее по адресу http://paste.lisp.org/display/122996.

Эта ошибка воспроизводится как с Apache 2.2, так и с mod-wsgi, а также со встроенным тестовым сервером Django (см. ниже).

Если я перейду непосредственно к относительному URL-адресу /password_change/, я увижу форму смены пароля, как и ожидалось.

Странно то, что все тесты, которые я написал для проверки этого, проходят и дают ожидаемый результат. См., например, testIndexUrl , testIndexView и test_password_change_url.

Вы можете запустить тесты из каталога bixproj с помощью

python manage.py test

Если вы хотите попытаться воспроизвести эту ошибку, это сравнительно легко.

Сначала загрузите проект (bixproj) и репозитории приложений (bixfile). Так

hg clone ssh://[email protected]/faheem/bixproj
hg clone ssh://[email protected]/faheem/bixfile

Затем убедитесь, что bixfile находится в пути Python. Измените БАЗЫ ДАННЫХ, чтобы использовать sqlite. Затем измените

LOGIN_URL = '/'+BIXFILE_NAME+'/login/'
LOGIN_REDIRECT_URL= '/'+BIXFILE_NAME+'/'

to

LOGIN_URL = '/login/'
LOGIN_REDIRECT_URL= '/'

Затем работает

python manage.py runserver

в каталоге bixproj на локальном компьютере и при переходе к URL-адресу по умолчанию http://127.0.0.1:8000/ должно отображаться сообщение об ошибке.

Я ожидаю, что смогу создать минимальный пример, показывающий ошибку, если это необходимо, но я действительно надеюсь, что эта ошибка очевидна, и мне это не нужно. Заранее спасибо.


person Faheem Mitha    schedule 28.06.2011    source источник


Ответы (1)


Ваш bixfiles.urls использует reverse. Это невозможно, потому что URL-адреса не были загружены при вызове reverse.

В Django 1.4 будет функция reverse_lazy, которая решит Эта проблема.

А пока вы можете:

  1. Внедрите reverse_lazy в свой проект (см. набор изменений 16121).
  2. Жестко кодируйте URL-адреса вместо использования реверса
person Alasdair    schedule 28.06.2011
comment
@Alasdair: я пробовал как reverse_lazy, так и жестко кодировать аргумент post_change_redirect вместо использования reverse, как вы предложили. К сожалению, ни один из этих методов не работает. Я получаю точно такую ​​же ошибку, как и раньше. Обратите внимание, что я использую reverse очень похожим образом в urls.py чуть выше проблемной записи без проблем. Вы тестировали это предложенное исправление? - person Faheem Mitha; 29.06.2011
comment
Да, я тестировал. Когда я заменил все перевернутые URL-адреса в bixfiles.urls.py на '/', у меня заработала индексная страница. - person Alasdair; 29.06.2011
comment
Чтобы пояснить мой предыдущий комментарий, я считаю, что проблема не reverse в шаблоне URL-адреса для индексной страницы, а в использовании reverse в любом шаблоне URL-адреса. Вы пытались полностью удалить реверс из своих URL-адресов? Это сработало для меня. - person Alasdair; 29.06.2011
comment
@Alasdair: я заменил reverse everywhere with reverse_lazy, per the link you posted. To define reverse_lazy`, я сделал from django.core.urlresolvers import reverse, from django.utils.functional import lazy, reverse_lazy = lazy(reverse, str). Это работает, так что похоже, что это действительно была проблема. Большое спасибо за вашу помощь в этом. - person Faheem Mitha; 29.06.2011
comment
К сожалению, сообщение об ошибке настолько бесполезно и не дает никакого намека на проблему. Нельзя ли что-то с этим сделать? Кроме того, документация версии 1.2 не дает никаких намеков на то, что reverse является проблематичным и может вызвать трудно отслеживаемые сбои. Если reverse_lazy решает проблему, почему бы не сделать его по умолчанию? - person Faheem Mitha; 29.06.2011
comment
Я рад, что у тебя все получилось. Я согласен, что это неприятная ошибка. Не сразу видно, что URL-адрес не совпадает, потому что вы использовали реверс в шаблонах URL-адресов. Я предложил группе разработчиков django добавить дополнительный пример в документацию lazy_reverse. об использовании его в шаблонах URL. - person Alasdair; 30.06.2011