Felder und base_fields - Django
Beim erstellen einer flatpage, möchte ich den Benutzer wählen Sie eine Vorlage aus einer vordefinierten Liste. Um die Flatpage
Modell unberührt, ich bevorzuge ChoiceField
über ModelChoiceField
(letztere bietet die PK von der Vorlage, aber ich brauche den Namen für das Feld Vorlagenname):
class NewFlatpageForm(FlatpageForm):
template_name = forms.ChoiceField(choices = [])
def __init__(self, *args, **kwargs):
self.base_fields['template_name'].choices = ProjectTemplate.objects.values_list('path', 'name')
super(NewFlatpageForm, self).__init__(*args, **kwargs)
Ich überschreiben __init__
oder Django füllt Entscheidungen, die auf dem server starten und nicht aktualisieren die Liste dann.
Habe ich keine admin Erfahrung, aber ich habe ähnliche Dinge mit den fields
- Attribut, wenn Sie nicht mit admin. Aber in diesem Fall habe ich eine Ausnahme erzählen fields
ist nicht ein Attribut des Formulars. __dict__
zeigte mir, es gibt eine base_fields
Attribut und es funktioniert. Also, warum verwenden base_fields hier, und warum ist fields
nicht anwesend ist, und endlich mache ich etwas hacky?
Du musst angemeldet sein, um einen Kommentar abzugeben.
fields
existiert nicht, bis nach, die Sie angerufen habensuper
. So einfach tauschen Sie die Reihenfolge der Zeilen, so dasssuper
kommt zuerst.Lektion aus meiner eigenen Erfahrung: ändern basefields bedeutet, dass Ihre änderungen bleiben, um "ewig" (bis python-exits). In deinem Fall wahrscheinlich kein problem, da Sie immer mit dem gleichen Feld-Namen, und ersetzen Sie Ihre Werte mit der Zuordnung von ProjectTemplate...
In meinem Fall, ich wollte ganz verschiedenen Bereichen, basierend auf Parameter im Konstruktor. Da meine Feld-Namen wurden in der Regel anders, jedes mal, wenn ich instanziiert eine form, die ich Hinzugefügt neue Felder ab, aber nicht beseitigen die aus der letzten Zeit.
Durch Aufruf von super früh (wie hier angegeben) und dann meine dynamische änderungen selbst.Felder anstelle von selbst.basefields, ich war in der Lage das problem zu beseitigen, eine ständig wachsende Liste von Feldern. Es macht absolut Sinn, jetzt, aber ich war nicht vertraut mit all den syntax-details und hackte durch, anstatt zu versuchen zu verstehen, es zuerst.
Neben Joe Germuska. Wenn Sie wirklich brauchen, um zu ändern, das Formular basierend auf der Anfrage, können Sie eine deepcopy um sicherzustellen, dass nichts geändert wird per Referenz: