Wenn ich ein Django-Formular habe wie:
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField()
sender = forms.EmailField()
Und ich rufe die as_table () -Methode einer Instanz dieses Formulars auf. Django rendert die Felder in derselben Reihenfolge wie oben angegeben.
Meine Frage ist, woher weiß Django die Reihenfolge, in der Klassenvariablen definiert wurden?
(Wie überschreibe ich diese Reihenfolge, wenn ich beispielsweise ein Feld aus der Init- Methode der Klasse hinzufügen möchte ?)
quelle
Neu in Django 1.9 sind Form.field_order und Form.order_fields () .
quelle
Ich ging voran und beantwortete meine eigene Frage. Hier ist die Antwort zum späteren Nachschlagen:
In Django
form.py
wird dunkle Magie mit der__new__
Methode ausgeführt, um Ihre Klassenvariablen letztendlich inself.fields
der in der Klasse definierten Reihenfolge zu laden .self.fields
ist eine Django-SortedDict
Instanz (definiert indatastructures.py
).Um dies zu überschreiben, sagen Sie in meinem Beispiel, dass der Absender an erster Stelle stehen soll, aber in einer Init- Methode hinzugefügt werden muss , würden Sie Folgendes tun:
quelle
self.fields.insert( 0, 'sender', self.fields['sender'] )
Felder werden in der Reihenfolge aufgelistet, in der sie in ModelClass._meta.fields definiert sind. Wenn Sie jedoch die Reihenfolge in Form ändern möchten, können Sie dies mit der Funktion keyOrder tun. Zum Beispiel :
quelle
Mit Django> = 1.7 müssen Sie
ContactForm.base_fields
Folgendes ändern :Dieser Trick wird in Django Admin
PasswordChangeForm
: Source auf Github verwendetquelle
PasswordChangeForm
die Reihenfolge der Felder geändert haben. Ihr Beispiel war also sehr nützlich für mich. Es scheint, dass es daranbase_fields
liegt, dass es nicht in die Unterklasse übertragen wird. Die Lösung scheintPasswordChangeFormSubclass.base_fields = PasswordChangeForm.base_fields
nach der Definition von `PasswordChangeFormSubclassContactForm.base_fields[k]
wenn Sie das bestellte Diktat erstellen . Es gibt einen Tippfehler in der Antwort, ich werde bearbeitenFormularfelder haben ein Attribut für die Erstellungsreihenfolge, das aufgerufen wird
creation_counter
..fields
Attribut ist ein Wörterbuch, dahercreation_counter
sollte es ausreichen , das Wörterbuch einfach hinzuzufügen und Attribute in allen Feldern zu ändern , um die neue Reihenfolge widerzuspiegeln (dies wurde jedoch nie versucht).quelle
Verwenden Sie einen Zähler in der Field-Klasse. Sortieren nach diesem Zähler:
Ausgabe:
quelle
Ab Django 1.7-Formularen wird OrderedDict verwendet, das den Append-Operator nicht unterstützt. Sie müssen das Wörterbuch also von Grund auf neu erstellen ...
quelle
Zum späteren Nachschlagen: Die Dinge haben sich seit den neuen Formen ein wenig geändert. Dies ist eine Möglichkeit, Felder aus Basisformelklassen neu zu ordnen, über die Sie keine Kontrolle haben:
Außerdem gibt es eine kleine Dokumentation zu SortedDict,
base_fields
die hier verwendet wird: http://code.djangoproject.com/wiki/SortedDictquelle
Wenn entweder
fields = '__all__'
:oder
exclude
verwendet werden:Dann verweist Django auf die im Modell definierte Reihenfolge der Felder . Das hat mich nur erwischt, also dachte ich, ich würde es erwähnen. In den ModelForm-Dokumenten wird darauf verwiesen :
quelle
Der einfachste Weg, Felder in Django 1.9-Formularen zu bestellen, ist die Verwendung
field_order
in Ihrem Formular Form.field_orderHier ist ein kleines Beispiel
Dies zeigt alles in der Reihenfolge an, die Sie in
field_order
dict angegeben haben.quelle
Die Verwendung
fields
in der innerenMeta
Klasse hat für mich funktioniertDjango==1.6.5
:So einfach ist das.
quelle
django.forms
funktioniert nichtDies hat mit der Metaklasse zu tun, die beim Definieren der Formularklasse verwendet wird. Ich denke, es führt eine interne Liste der Felder und wenn Sie in die Mitte der Liste einfügen, könnte es funktionieren. Es ist eine Weile her, seit ich mir diesen Code angesehen habe.
quelle
Ich habe dies verwendet, um Felder zu verschieben über:
Dies funktioniert in Version 1.5 und ich bin mir ziemlich sicher, dass es auch in neueren Versionen funktioniert.
quelle