[PYTHON] Fügen Sie Formularobjekten mit Django dynamisch Felder hinzu

Ich habe den Inhalt ausprobiert, der neben Dynamische Spezifikation des Abfragesatzes von ModelChoiceField in Django geschrieben wurde, also Memo Memo.

Letzte Hausaufgaben

Durch Spielen mit Form.fields können Sie verschiedene Attribute anderer Felder ändern, nachdem das Formular erstellt wurde. Ist es möglich, das Feld selbst hinzuzufügen / zu entfernen?

Ich habe es tatsächlich versucht

Starten Sie den Shell-Befehl von Django und probieren Sie ihn in einer interaktiven Shell aus

Erstellen Sie ein leeres Formularobjekt

>>> from django import forms
>>> f = forms.Form()
>>> f.as_p()
''
>>> f.fields
OrderedDict()

Zu diesem Zeitpunkt sind keine Felder definiert, sodass beim Aufrufen von "as_p ()" nichts gerendert wird Form.fields zeigt nur leere OrderdDict-Objekte an

… Zum ersten Mal wissen wir, dass der Typ von Form.fields eine Klasse namens [OrderedDict] ist (https://docs.python.org/3/library/collections.html#collections.OrderedDict).

Fügen Sie Felder zu "Form.fields" hinzu

>>> f.fields['name'] = forms.CharField(label='Name')
>>> f.as_p()
'<p><label for="id_name">Name:</label> <input id="id_name" name="name" type="text" /></p>'

>>> f.fields
OrderedDict([('name', <django.forms.fields.CharField object at 0x00000000045E5B388>)])

Fügen Sie "CharField" mit dem Schlüsselnamen hinzu. Es wird ordnungsgemäß mit as_p () gerendert. Der Inhalt von "Form.fields" enthält auch das Objekt "CharField" mit dem Schlüssel "Name".

Rufen Sie is_valid () auf und überprüfen Sie Fehler, clean_data

>>> f.is_valid()
Flase

>>> f.errors
{}

>>> f.cleaned_data
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Form' object has no attribute 'cleaned_data'

Da das hinzugefügte Namensfeld "erforderlich = wahr" (Standardwert) ist, wird erwartet, dass "is_valid ()" falsch ist, aber aus irgendeinem Grund "Form.errors" leer ist.

Wenn das "Form" -Objekt den Wert jedes Feldes nicht geändert oder keine "Daten" in seinem Argument erhalten hätte, würde es beim Nachschlagen nur einen leeren "Fehler" erzeugen und "full_clean ()" behandeln Es scheint zu Ende zu gehen (bereinigte_Daten werden ebenfalls nicht generiert).

Es gibt keine Hilfe dafür. Übergeben Sie daher das Argument "data" an das Objekt "Form" und generieren Sie es neu. Ich werde es versuchen.

>>> f = forms.Form(data={})
>>> f.fields['name'] = forms.CharField(label='Name')
>>> f.is_valid()
False

>>> f.errors
{'name': ['This field is required.']}

>>> f.cleaned_data
{}

Wie erwartet enthielt der Inhalt von "Fehlern" einen obligatorischen Überprüfungsfehler für "Name". Ein leeres Diktat wird auch für "bereinigte_Daten" generiert.

Umweg: Verhalten von "is_valid ()" und "error"

Zuerst habe ich versucht, Form.data direkt ein leeres Diktat zuzuweisen, um das Problem von ↑ zu lösen, aber das Ergebnis hat sich nicht geändert. Als ich der Quelle von Django folgte, war dies auf die folgende Verarbeitung am Anfang von __init __ () der BaseForm-Klasse zurückzuführen, die das übergeordnete Element der Form-Klasse ist.

forms.py


        self.is_bound = data is not None or files is not None

Die Implementierung von "is_valid" ist also nur eine Zeile weiter unten

forms.py


    def is_valid(self):
        """
        Returns True if the form has no errors. Otherwise, False. If errors are
        being ignored, returns False.
        """
        return self.is_bound and not bool(self.errors)

Darüber hinaus werden Fehler als Methoden mit Eigenschaftsdekoratoren und nicht als Felder definiert.

forms.py


    @property
    def errors(self):
        "Returns an ErrorDict for the data provided for the form"
        if self._errors is None:
            self.full_clean()
        return self._errors

Es reichte also nicht aus, "Daten" direkt zu bearbeiten, und die folgenden beiden Prozesse waren erforderlich.

Wenn Sie darüber nachdenken, es als normale Webanwendung zu verwenden, sollten Sie die Parameter nicht ändern und die Validierung wiederholen müssen, während Sie eine Anfrage bearbeiten ... Es ist natürlich, dass die Validierung (Aufruf von "full_clean ()") nicht jedes Mal ausgeführt wird, wenn auf "is_valid ()" oder "error" zugegriffen wird, sondern nur beim ersten Mal.

Ändern Sie "Daten" so, dass die Validierung "Wahr" ist

>>> f.data = {'name':'hoge'}
>>> f.full_clean()
>>> f.is_valid()
True

>>> f.errors
{}

>>> f.cleaned_data
{'name':'hoge'}

Versuchen Sie, weitere Felder hinzuzufügen

>>> f.fields['date'] = forms.DateField(label='Datum',required=False)

>>> f.as_p()
'<ul class="errorlist"><li>This field is required.</li></ul>\n<p><label for="id_name">Name:</label> <input id="id_name" name="name" type="text" /></p>\n<p><label for="id_date">Datum:</label> <input id="id_date" name="date" type="text" /></p>'

>>> f.fields
OrderedDict([('name', <django.forms.fields.CharField object at 0x00000000045E5B38>), ('date', <django.forms.fields.DateField object at 0x0000000002A3C828>)])

>>> f.full_clean()
>>> f.is_valid()
True

>>> f.errors
{}

>>> f.cleaned_data
{'date':None, 'name':'hoge'}

>>> f.data['date'] = '2014-12-04'
>>> f.full_clean()
>>> f.is_valid()
True

>>> f.errors
{}

>>> f.cleaned_data
{'date':datetime.date(2014, 12, 4), 'name':'hoge'}

Entfernen Sie Felder aus Form.fields

>>> f.fields.popitem()
('date', <django.forms.fields.DateField object at 0x0000000002A3C828>)

>>> f.as_p()
'<p><label for="id_name">Name:</label> <input id="id_name" name="name" type="text" value="hoge" /></p>'

>>> f.fields
OrderedDict([('name', <django.forms.fields.CharField object at 0x00000000045E5B38>)])

>>> f.full_clean()
>>> f.cleaned_data
{'name': 'hoge'}

>>> f.data
{'date': '2014-12-04', 'name': 'hoge'}

Form.fields löscht den Artikel mit OrderedDict.popitem. Wenn das Argument last True ist (Standard), ist es LIFO, und wenn es False ist, ist es LILO. Diesmal ist es wahr, daher wurde das Datumsfeld, das ich später hinzugefügt habe, entfernt.

Zusammenfassung

… Djangos 'Form'-Objekt kann also später im Feld selbst hinzugefügt / entfernt werden. Ich denke, es kann auf Anfragen wie "Ermöglichen Sie das freie Hinzufügen von Bildschirmeingabeelementen in den Master-Einstellungen!" Reagieren.

Recommended Posts

Fügen Sie Formularobjekten mit Django dynamisch Felder hinzu
Fügen Sie in Django dynamisch Formularfelder hinzu
So erhalten Sie mehrere Modellobjekte zufällig in Django
Setzen Sie DateField des Formulars in Django auf type = date
Implementieren von Formularschaltflächen zum Hinzufügen in Django Inline Form Set Part2
Implementieren Sie eine Schaltfläche zum Hinzufügen eines Formulars im Django-Inline-Formularsatz
[Django] So testen Sie Form [TDD]
Legen Sie Platzhalter in Eingabefeldern in Django fest
Fügen Sie mit ArcPy Felder zu Features hinzu
Fehler im Zusammenhang mit Memcached in Django
Wie man CSS in Django reflektiert
6 Möglichkeiten zum Stringen von Objekten in Python
Dynamisches Definieren von Variablen in Python
So löschen Sie abgelaufene Sitzungen in Django
Mindestkenntnisse zur Verwendung von Form with Flask
Fügen Sie in Jupyter IPerl zum Kernel hinzu.
Geben Sie das ModelChoiceField-Abfrageset in Django dynamisch an
So füllen Sie mit Python dynamisch Nullen aus
So führen Sie vom Server gesendete Ereignisse in Django durch
[Django-Memo] Ich möchte die angemeldeten Benutzerinformationen im Voraus im Formular festlegen.
Ermöglichen Sie die Verwendung von HTML5 <input type = "date / time"> im DatetimeField-Formular in Django
Hinzufügen einer Pre-Save-Verarbeitung beim Hinzufügen eines Objekts auf der Django-Verwaltungssite
Versuchen Sie, mit django-import-export csv-Daten zu django hinzuzufügen
So implementieren Sie Rails-Helfer-ähnliche Funktionen in Django
Ich möchte Datetime.now in Djangos Test reparieren
Speichern Sie mehrere Modelle in einem Formular mit Django
So reflektieren Sie ImageField in Django + Docker (Kissen)
Dynamisches Ersetzen der nächsten Methode in Python
So fügen Sie Python ein Modul hinzu, das Sie in Julialang eingefügt haben
Übergeben Sie Login-Benutzerinformationen, um sie in Django anzuzeigen
So erstellen Sie eine Rest-API in Django
Fügen Sie Funktionen zum Ändern der Django-Tagesschichtinformationen hinzu
Fügen Sie mit Pandas Summen zu Zeilen und Spalten hinzu
Django Anfrageformular 2
Modell in Django
Django Vorgeschlagene Form
Ich möchte eine Fehlermeldung auf Japanisch mit dem Django-Passwortänderungsformular ausgeben
Hebe die gefallenen Ohren von Django Form auf
Form in Django
Django Kontaktformular
[Python] [Django] Verwendung des Auswahlfelds und Hinzufügen von Optionen
Fügen Sie der EV3 Micropyhon-Programmierung in VS Code eine automatische Ergänzung hinzu
Mail-Formular zur serverlosen Webanwendung hinzufügen ~ Backend-Version ~
Verwendung von Bootstrap in der generischen Klassenansicht von Django
TemplateView-Muster, die Sie zuerst in Django lernen möchten
Vorbereiten der Steuerung von Nashornobjekten mit Skripten in Grasshopper / Python
So fügen Sie einer PDF-Datei Seitenzahlen hinzu (in Python)
Django / Verwandte Objekte (Hinzufügen, Erstellen, Entfernen, Löschen, Festlegen) Zusammenfassung
Erstellen Sie mit Django dynamisch Tabellen im Schema und generieren Sie dynamisch Modelle
Hochladen von Dateien in der generischen Klassenansicht von Django
Wie man Decorator in Django benutzt und wie man es macht
So fügen Sie dem Balkendiagramm von matplotlib einen Farbbalken hinzu
So verweisen Sie auf statische Dateien in einem Django-Projekt
[Django] Eine Geschichte über das Feststecken in einem Sumpf beim Versuch, einen Reißverschluss mit einem Formular zu validieren [TDD]