Как мне отправить форму, указав только исходный код HTML?
-
19-08-2019 - |
Вопрос
Я хотел бы иметь возможность отправить форму в Исходный код 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.
ХТХ.
Проверьте механизировать или это обертка саржа.Я думаю, что это Клиентская форма модуль будет работать на вас.