Подтвердить что ты не робот

Django render_to_string() игнорирует {% csrf_token%}

Я пытаюсь выполнить модульные тесты в Django. У меня есть следующая форма в index.html:

<form method=POST>
  {% csrf_token %}
  <input name=itemT>
</form>

И я проверяю, правильно ли отображает шаблон:

views.py

def homePage(request):
    return render(request, 'index.html')

tests.py:

request = HttpRequest()

response = homePage(request)
if response:
    response = response.content.decode('UTF-8')

expectedHTML = render_to_string('index.html')
self.assertEqual(response, expectedHTML)

response имеет скрытое поле ввода с токеном csrf; однако expectedHTML не существует (есть только пустая строка в месте {% csrf_token %}). Таким образом, утверждение всегда терпит неудачу.

Можно ли создать render_to_string() поле ввода csrf? Если это так, будет ли токен response таким же, как и у expectedHTML?

Или, есть ли способ игнорировать поле ввода, чтобы тест мог быть успешным?

4b9b3361

Ответ 1

Чтобы использовать токен csrf при использовании render_to_string, вам нужно предоставить объект request, чтобы выполнялись контекстные процессоры.

В Django 1.8+ вы можете просто передать запрос в качестве аргумента

return render_to_string('index.html', request=request)

В более ранних версиях вы можете использовать RequestContext.

from django.template import RequestContext
render_to_string('index.html', context_instance=RequestContext(request))

Ответ 2

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

К сожалению, принятый ответ не будет работать с Django 1.10 при изменении csrf_token для каждого запроса. См. этот метод, который работает 1.10. (Изменен код немного, чтобы исправить опечатку из оригинальной точки)

class HomePageTest(TestCase):

    @staticmethod
    def remove_csrf(html_code):
        csrf_regex = r'<input[^>]+csrfmiddlewaretoken[^>]+>'
        return re.sub(csrf_regex, '', html_code)

    def assertEqualExceptCSRF(self, html_code1, html_code2):
        return self.assertEqual(
            self.remove_csrf(html_code1),
            self.remove_csrf(html_code2)
        )

Ответ 3

Вы можете просто добавить такой аргумент.

render_to_string('index.html', request=request)

Обратитесь к .