"admin" не является зарегистрированным пространством имен в Django 1.4
Я пытаюсь обновить довольно большой проект Django до недавно выпущенного Django 1.4, и у меня возникают некоторые проблемы при запуске python manage.py test
.
Многие внутренние тесты, прошедшие в Django 1.3, теперь терпят неудачу, причем действительно нечетные сообщения, которые я не могу исправить. Наиболее показательным является:
NoReverseMatch: u'admin' is not a registered namespace
Это вызвано для тестов django.contrib.auth
для изменения пароля, в частности (один из которых - test_password_change_fails_with_mismatched_passwords (django.contrib.auth.tests.views.ChangePasswordTest)
. Странно, что пространство имен зарегистрировано правильно, а приложение отлично работает. Я импортирую администратора в "новый" способ:
url(r'^admin/', include(admin.site.urls)),
Когда я говорю об этой ошибке в частности, все, что я могу найти, это люди, импортирующие URL-адреса администратора с использованием старой схемы и ничего не относящиеся к этой проблеме вообще.
Я попытался удалить приложения из INSTALLED_APPS
один за другим, но тесты auth просто не пройдут. Кроме того, когда я загружаю интерпретатор Python из python manage.py shell
и выполняю reverse('admin:index')
, URL-адрес разрешается до /admin/
без ошибок. Я внимательно прочитал код и не вижу, где это может упасть.
Как я упоминал ранее, это не единственная ошибка, которая возникает. Я также получаю AttributeError: AUTH_PROFILE_MODULE
из теста test_site_profile_not_available (django.contrib.auth.tests.models.ProfileTestCase)
, хотя AUTH_PROFILE_MODULE
определен в моем файле settings.py
. Как могут тесты собственного Django быть неудачными?
Ответы
Ответ 1
Как оказалось, это было связано с порядком ключа TEMPLATE_LOADERS
в моем файле настроек.
У меня было следующее:
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.Loader',
'django.template.loaders.filesystem.Loader',
)
который каким-то образом вызвал ошибку при изменении адресов администратора. Переключение двух раундов решило проблему. Я хотел бы знать, как это происходит, поскольку оно не воспроизводится в пустом проекте Django 1.4.
То, что было воспроизводимым, было AttributeError
для settings.AUTH_PROFILE_MODULE
. Оказывается, это ошибка в Django 1.4, которая была отправлена в день выпуска здесь.
Ответ 2
Короткий ответ: У вас есть копия файлов шаблонов admin в Django, скопированных в каталоге ваших шаблонов приложений из более ранней версии Django, после чего вы обновили Django, но не обновили (перепрограммировать ) эти локальные шаблоны.
Длинный ответ:. Основной причиной этой проблемы является использование более старой версии файлов шаблонов администратора Django (которые установлены там, где установлена сама django, обычно это каталог python site-packages
или dist-packages
)), В Django 1.5 есть обратное несовместимое изменение в теге шаблона url, в котором первым параметром должна быть строка из примечаний к выпуску Django 1.5:
Одна устаревшая функция, которую стоит отметить, - это переход на "новый стиль" тег. До Django 1.3 синтаксис, подобный {% url myview%}, был интерпретирован неправильно (Django считается "myview" как буквальное имя view, а не переменной шаблона с именем myview). Django 1.3 и выше ввел синтаксис {% load url from future%}, чтобы ввести исправленное поведение, когда myview рассматривалось как переменная.
Итак, проблема в том, что у вас есть копия файлов шаблонов администратора в одной из ваших шаблонов шаблонов приложений, которая копируется из более ранней версии Django. Обычно это делается для переопределения шаблонов администрирования по умолчанию. Из-за отмеченного обратного несовместимого изменения этот устаревший файл шаблона не может загружаться в более новой среде Django и вызывает странную ошибку: NoReverseMatch: u'admin' is not a registered namespace
.
Изменение порядка записей TEMPLATE_LOADERS
будет игнорировать изменения в локальных административных шаблонах в пользу файла шаблонов по умолчанию (поскольку шаблоны Django по умолчанию загружаются полным путем с помощью filesystem.Loader
). Если изменения необходимы (как правило, это так), вы должны обновить файлы своего локального администратора с помощью новых шаблонов установки Django и повторно применить к ним свои изменения.
Примечание 1: Аналогичная ситуация возникает, когда локальные шаблоны администратора новее, чем установка по умолчанию в Django, что, похоже, это ваш случай. Аналогичным образом, лучшим решением является обновление всех копий шаблонов администратора.
Примечание 2: Другая возможность получения такой ошибки - при использовании virtualenv. Например, если вы запускаете проект с помощью virtualenv, но элемент TEMPLATE_DIRS
для шаблонов администратора Django относится к вашей глобальной установке python, вы можете получить эту ошибку.
Ответ 3
Попробуйте добавить namespace = "admin" внутри метода include в файле urls.py.
ex: url (r '^ admin/', include ( "someUrlpattern", namespace = "admin" ))
Ответ 4
Пользовательский загрузчик шаблонов app_directories загружает шаблоны из каталога шаблонов INSTALLED_APPS, а загрузчик файловой системы загружает их из каталога шаблонов, настроенного в настройках TEMPLATE_DIRS.
Переключение двух из них имеет огромное значение, потому что если у вас есть пользовательские шаблоны в вашем приложении, он не будет загружаться, если app_directories находится наверху. Если загрузчик файловой системы находится вверху, django будет искать шаблон в каталоге шаблона сначала перед загрузкой по умолчанию из установленного_apps.
Вот почему он не воспроизводится в пустом проекте Django. Он будет искать шаблоны в нужных местах.
Ответ 5
Мое решение состояло в том, чтобы обновить django до новейшего переливания:
pip install --upgrade django == 1.6.1
перед этим проверьте установленную версию:
замерзание | grep Django
- Я обнаружил, что на сервере выпуска была старая версия, обновление решило эту проблему!
Ответ 6
У меня было подобное сообщение об ошибке со мной, потому что у моих URL-адресов conf было определено 2 logout
URL.
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='home.html'), name='home'),
url(r'^api/v1/', include(router.urls)),
url(r'^logout/$', auth_views.logout, name='logout'),
url(r'^login/$', auth_views.login, {'template_name': 'login.html'}, name='login'),
url(r'^logout/$', auth_views.logout, {'template_name': 'logged_out.html'}, name='logout'),
]