Como faço para enviar um formulário dado apenas HTML?
-
19-08-2019 - |
Pergunta
Eu gostaria de ser capaz de enviar um formulário em um HTML (string) . Em outras palavras eu preciso pelo menos a capacidade de gerar parâmetros POST a partir de uma string contendo código HTML da forma . Isso é necessário em testes de unidade para um projeto Django. Eu gostaria de uma solução que possivelmente;
- Usa biblioteca único padrão Python e Django.
- Permite geração de parâmetro de um formulário específico, se houver mais do que uma forma actual.
- Permite-me para alterar os valores antes da submissão.
Uma solução que retorna um (Django) instância forma a partir de uma dada classe de formulário é melhor. Porque ele me permitiria usar a validação. Idealmente, iria consumir a fonte (que é uma string), uma classe de formulário e, opcionalmente, um nome de formulário e retornar a instância como era antes de renderização.
NOTA: Eu estou ciente isso não é uma tarefa fácil e, provavelmente, os ganhos dificilmente justificar o esforço necessário. Mas eu sou apenas curioso sobre como isso pode ser feito, de forma prática e confiável. Se possível.
Solução
Você deve reler o href="http://docs.djangoproject.com/en/dev/topics/testing/" rel="nofollow noreferrer"> documentação , especificamente a parte sobre o teste de vista (e) com formas o cliente de teste .
O cliente de teste funciona como um navegador web simples, e permite que você faça GET
e POST
pedidos para seus pontos de vista Django. Você pode ler a resposta HTML ou obter o mesmo objeto Context
o modelo recebeu. Seu objeto Context
deve conter a instância forms.Form
real que você está procurando.
Por exemplo, se a sua vista no /form/
URL passa o {'myform': forms.Form()}
contexto para o modelo, você pode obtê-lo desta maneira:
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)
Esperamos que realiza o que quiser, sem ter que mexer com a análise de HTML.
Editar : Depois que eu voltar a ler os docs Django sobre Formulários, verifica-se que as formas são imutáveis. Tudo bem, embora, basta criar uma nova instância Form
e alegam que; Eu mudei meu exemplo de código para corresponder a este.
Outras dicas
Uma vez que a estrutura de teste Django faz isso, eu não tenho certeza que você está pedindo.
Você quer testar uma aplicação Django que tem uma forma?
- No caso, você precisa fazer um GET inicial
- seguido pelo resultando POST
Você quer write (e teste) uma aplicação Django que envia um formulário para outro site?
Veja como testar aplicações Django com formulários.
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")
Nota - nós não analisar o HTML em detalhe. Se ele tem o modelo certo e tem a cadeia de resposta certa, ele tem que estar certo.
É simples ... e difícil ao mesmo tempo.
Disclaimer: Eu não sei muito sobre Python e nada sobre Django ... Então eu dou linguagem agnóstico conselhos gerais, ...
Se um dos conselhos acima não funciona para você, você pode querer fazê-lo manualmente:
- Carregue a página com um analisador HTML, lista as formas.
- Se o atributo
method
é POST (case insensitive), obter o atributoaction
para obter o URL do pedido (pode ser relativo). - No formulário, obter todas as tags
input
eselect
. Os atributosname
(ouid
Se nenhum nome) são as chaves dos parâmetros do pedido. Os atributosvalue
(esvaziar se ausente) são os valores correspondentes. - Para
select
, o valor é o daoption
selecionado ou o texto apresentado nenhum atributovalue
.
Estes nomes e valores devem ser URL codificado em solicitações GET, mas não os POST.
HTH.
Confira mecanizar ou é invólucro sarja . Eu acho que é ClientForm módulo irá trabalhar para você.