Тестовый клиент Django перенаправляет вошедших пользователей на страницу авторизации
Я знаю, что этот вопрос уже задавался, но ни один из ответов мне не подходит.
Когда я пытаюсь использовать клиентский логин в тестах Django, он в основном игнорируется, и я получаю перенаправление на страницу входа. После нескольких тестов я заметил, что он правильно регистрирует меня, но выкидывает из системы, когда я его использую.
Вот урезанная версия моего кода, которая все еще воспроизводит это.
from django.auth import get_user
class MapListViewTest(TestCase):
@classmethod
def setUpTestData(cls):
# Create a user
cls.user = get_user_model().objects.create(username="testuser")
cls.user.set_password("password")
cls.user.save()
# [...]
def setUp(self):
self.client.login(
username=self.user.get_username(), password=self.user.password
)
def test_map_list_view_renders(self):
"""Test that the MapListView renders successfully and includes a list of maps."""
logger.info(get_user(self.client)) # <-- <django.contrib.auth.models.AnonymousUser object at 0x7377d5589540>
self.client.login(
username=self.user.get_username(), password=self.user.password
)
logger.info(get_user(self.client)) # <-- <Profile: testuser>
response = self.client.get(reverse("map_list"), follow=True)
logger.info(get_user(self.client)) # <-- <django.contrib.auth.models.AnonymousUser object at 0x7377d5589540>
self.assertEqual(response.status_code, 200) # <-- OK
self.assertTemplateUsed(response, "map_list.html") # <-- lands on 'account/login.html'
(я поместил его дважды здесь в сниппете, но в реальном коде он находится только в setUp)
Не знаю, имеет ли это значение, но перенаправление меняет адрес с http://localhost/...
на http://testserver/...
, а я работаю в контейнере docker.
Кроме того, модель пользователя наследуется от AbstractUser и не имеет собственной логики при входе в систему.
В self.client.login
self.client.login(
username=self.user.get_username(), password=self.user.password
)
Здесь self.user.password
не работает, потому что это хэшированный пароль, в то время как метод ожидает пароль в виде обычного текста.
Попробуйте эти
self.client.login(username=self.user.get_username(), password="password")
Мы заменяем self.user.password
на "password"
, чтобы получить пароль открытым текстом.
попробуйте удалить follow=True
, чтобы увидеть, куда именно ведет первоначальное перенаправление и почему отображается страница входа в систему.
Согласно ошибке, Django пытается отправить вас на нужную страницу после подключения, но есть несоответствие между используемыми доменными именами (localhost и testserver).
Попробуйте добавить следующее в файл settings.py
ALLOWED_HOSTS = ['testserver', 'localhost']
Это позволяет этим двум доменам быть авторизованными в запросах