Как мне отправить форму, указав только исходный код HTML?

StackOverflow https://stackoverflow.com/questions/343622

Вопрос

Я хотел бы иметь возможность отправить форму в Исходный код HTML (строка).Другими словами, мне нужна, по крайней мере, возможность генерировать параметры POST из строки, содержащей HTML-исходный код формы.Это необходимо в модульных тестах для проекта Django.Я хотел бы найти решение, которое, возможно;

  • Использует только стандартную библиотеку Python и Django.
  • Позволяет генерировать параметры из определенной формы, если присутствует более одной формы.
  • Позволяет мне изменять значения перед отправкой.

Лучшим является решение, которое возвращает экземпляр формы (Django) из данного класса form.Потому что это позволило бы мне использовать валидацию.В идеале он должен использовать исходный код (который представляет собой строку), класс формы и, необязательно, имя формы и возвращать экземпляр таким, каким он был до рендеринга.

ПРИМЕЧАНИЕ:Я понимаю, что это непростая задача, и, вероятно, достигнутые результаты вряд ли оправдали бы необходимые усилия.Но мне просто любопытно, как это можно сделать практичным и надежным способом.Если это возможно.

Это было полезно?

Решение

Вам следует перечитать документация о платформе тестирования Django, в частности, часть о тестировании представлений (и форм) с тестовый клиент.

Тестовый клиент действует как простой веб-браузер и позволяет вам GET и POST запросы к вашим представлениям Django.Вы можете прочитать HTML-код ответа или получить то же самое Context возразите против полученного шаблона.Ваш Context объект должен содержать фактический forms.Form экземпляр, который вы ищете.

В качестве примера, если ваш просмотр по URL /form/ передает контекст {'myform': forms.Form()} к шаблону, вы могли бы добраться до него таким образом:

from django.test.client import Client
c = Client()

# request the web page:
response = c.get('/form/')

# get the Form object:
form = response.context['myform']

form_data = form.cleaned_data
my_form_data = {} # put your filled-out data in here...
form_data.update(my_form_data)

# submit the form back to the web page:
new_form = forms.Form(form_data)
if new_form.is_valid():
    c.post('/form/', new_form.cleaned_data)

Надеюсь, это достигнет того, чего вы хотите, без необходимости возиться с синтаксическим анализом HTML.

Редактировать:После того, как я перечитал документы Django о формах, оказывается, что формы неизменяемы.Однако это нормально, просто создайте новый Form инстанцию и представить, что;Я изменил свой пример кода, чтобы он соответствовал этому.

Другие советы

Поскольку тестовый фреймворк Django делает это, я не уверен, о чем вы спрашиваете.

Вы хотите протестировать приложение Django, которое имеет форму?

  • В этом случае вам нужно выполнить начальный GET
  • за которым следует итоговый ПОСТ

Вы хотите написать (и протестировать) приложение Django, которое отправляет форму на другой сайт?

Вот как мы тестируем приложения Django с помощью форм.

class Test_HTML_Change_User( django.test.TestCase ):
    fixtures = [ 'auth.json', 'someApp.json' ]
    def test_chg_user_1( self ):
        self.client.login( username='this', password='this' )
        response= self.client.get( "/support/html/user/2/change/" )
        self.assertEquals( 200, response.status_code )
        self.assertTemplateUsed( response, "someApp/user.html")

def test_chg_user( self ):
    self.client.login( username='this', password='this' )
    # The truly fussy would redo the test_chg_user_1 test here
    response= self.client.post(
        "/support/html/user/2/change/",
        {'web_services': 'P',
         'username':'olduser',
         'first_name':'asdf',
         'last_name':'asdf',
         'email':'asdf@asdf.com',
         'password1':'passw0rd',
         'password2':'passw0rd',} )
    self.assertRedirects(response, "/support/html/user/2/" )
    response= self.client.get( "/support/html/user/2/" )
    self.assertContains( response, "<h2>Users: Details for", status_code=200 )
    self.assertContains( response, "olduser" )
    self.assertTemplateUsed( response, "someApp/user_detail.html")

Примечание - мы не разбираем HTML в деталях.Если у него правильный шаблон и есть правильная строка ответа, он должен быть правильным.

Это очень просто...и в то же время тяжело.
Отказ от ответственности:Я мало что знаю о Python и вообще ничего о Django...Поэтому я даю общие, не зависящие от языка советы...Если один из приведенных выше советов у вас не работает, возможно, вы захотите сделать это вручную:

  • Загрузите страницу с помощью HTML-парсера, перечислите формы.
  • Если в method атрибут POST (не чувствителен к регистру), получаем action атрибут для получения URL-адреса запроса (может быть относительным).
  • В форме получите все input и select Теги.В name (или id если нет имени) атрибуты являются ключами параметров запроса.В value атрибуты (пустые, если отсутствуют) - это соответствующие значения.
  • Для select, значение является одним из выбранных option или отображаемый текст - нет value атрибут.

Эти имена и значения должны быть URL, закодированными в запросах GET, но не в запросах POST.

ХТХ.

Проверьте механизировать или это обертка саржа.Я думаю, что это Клиентская форма модуль будет работать на вас.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top