Frage

Ich möchte in der Lage sein, eine Form in einem HTML-Quelle (string) zu unterbreiten. Mit anderen Worten: Ich brauche mindestens die Fähigkeit POST-Parameter aus einem String mit HTML-Quelle der Form zu erzeugen. Dies ist in der Unit-Tests für ein Django-Projekt benötigt. Ich möchte eine Lösung, die möglicherweise;

  • Verwendet nur Standard-Python-Bibliothek und Django.
  • Ermöglicht Parametererzeugung von einer bestimmten Form, wenn es mehr als eine Form vorliegt.
  • Erlaubt mir die Werte vor der Vorlage zu ändern.

Eine Lösung, die eine (Django) Formularinstanz aus einer bestimmten Form Klasse zurückgibt, ist am besten. Weil es erlauben würde, mir die Validierung zu verwenden. Ideal wäre es, die Quelle verbrauchen (was ein String), eine Formularklasse, und optional einen Formularnamen und gibt die Instanz, wie es vor dem Rendern war.

Hinweis: Ich bin mir bewusst, dies keine leichte Aufgabe ist, und wahrscheinlich würden die Gewinne kaum den Aufwand rechtfertigen, die erforderlich. Aber ich bin nur neugierig, wie dies getan werden kann, in einer praktischen und zuverlässigen Art und Weise. Wenn möglich.

War es hilfreich?

Lösung

Sie sollten wieder lesen Sie die Dokumentation über Djangos Test-Framework , insbesondere der Teil über das testen Ansichten (und Formen) mit der Test-Client .

Der Test-Client fungiert als einfacher Web-Browser, und lässt Sie GET und POST Anfragen an Ihren Django Ansichten machen. Sie können die Antwort HTML lesen oder das gleiche Objekt Context die Vorlage erhalten erhalten. Ihr Context Objekt sollte die tatsächliche forms.Form Instanz enthalten Sie suchen.

Als Beispiel, wenn Ihr Blick auf die URL /form/ den Kontext {'myform': forms.Form()} auf die Vorlage gelangt, die Sie es auf diese Weise bekommen konnte:

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)

Hoffentlich erreicht, was Sie wollen, ohne mit Parsing HTML zu Chaos mit.

Bearbeiten : Nachdem ich die Django-Dokumentation über Forms neu lesen, es stellt sich heraus, dass Formen unveränderlich sind. Das ist in Ordnung, aber nur eine neue Form Instanz erstellen und einreichen, dass; Ich habe mein Codebeispiel geändert, dies zu entsprechen.

Andere Tipps

Da der Django-Test-Framework dies tut, ich bin mir nicht sicher, was Sie fragen.

Haben Sie eine Django App testen möchten, die eine Form hat?

  • In diesem Fall müssen Sie ein erstes GET tun
  • , gefolgt von dem resultierenden POST

Haben Sie (und Test) eine Django-app schreiben wollen, die ein Formular auf eine andere Website einreicht?

Hier ist, wie wir testen Django apps mit Formularen.

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")

Hinweis - wir analysieren nicht die HTML im Detail. Wenn es die richtige Vorlage und hat den richtigen Antwort-String, hat es richtig sein.

Es ist einfach ... und hart zugleich.
Disclaimer: Ich weiß nicht viel über Python und gar nichts über Django ... Also gebe ich allgemein sprachunabhängig Ratschläge ... Wenn eine der oben genannten Ratschläge nicht für Sie arbeiten, können Sie es manuell tun:

  • Laden Sie die Seite mit einem HTML-Parser, die Formulare auflisten.
  • Wenn das method Attribut POST (Groß- und Kleinschreibung) ist, erhalten das action Attribut die URL der Anforderung zu erhalten (kann relativ sein).
  • In der Form, erhalten alle input und select Tags. Die name (oder id Wenn kein Name) Attribute sind die Schlüssel der Anforderungsparameter. Die value Attribute (leer, wenn nicht vorhanden) sind die entsprechenden Werte.
  • Für select, der Wert ist derjenige, der ausgewählten option oder der angezeigte Text ist kein value Attribut.

Diese Namen und Werte müssen URL in GET-Requests codiert werden, aber nicht in POST denjenigen.

HTH.

Schauen Sie sich mechanize oder es ist Wrapper Köper . Ich denke, es ClientForm Modul für Sie arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top