Dynamisch Modelform der Meta-Klasse aktualisieren
-
08-07-2019 - |
Frage
Ich hoffe, dynamisch eine Inline-Meta-Klasse der Modelform zu aktualisieren aus meiner Sicht. Obwohl dieser Code der Ausschlussliste in der Meta-Klasse, die Ausgabe von as_p()
zu aktualisieren scheint, as_ul()
, etc. nicht die aktualisierte Meta ausschließen widerspiegelt.
Ich gehe davon aus, dass dann die HTML erzeugt wird, wenn die Modelform nicht erzeugt wird, wenn der as_*()
genannt wird. Gibt es eine Möglichkeit, die Aktualisierung der HTML zu zwingen?
Ist das auch der beste Weg, es zu tun? Ich nahm nur die sollte Arbeit.
Die Gedanken?
from django.forms import ModelForm
from testprogram.online_bookings.models import Passenger
class PassengerInfoForm(ModelForm):
def set_form_excludes(self, exclude_list):
self.Meta.exclude = excludes_list
class Meta:
model = Passenger
exclude = []
Lösung
Die Meta-Klasse wird verwendet, um dynamisch die Formulardefinition zu konstruieren -. So durch die Zeit, die Sie die Modelform Instanz erstellt haben, die Felder nicht in der exclude bereits als das neue Objekt die Attribute hinzugefügt
Der normale Weg, es zu tun Liste sein müsste nur mehrere Klassendefinitionen für jeden möglich auszuschließen. Aber wenn Sie das Formular selbst wollen dynamisch sein, erhalten Sie eine Klassendefinition on the fly erstellen müssen. So etwas wie:
def get_form(exclude_list):
class MyForm(ModelForm):
class Meta:
model = Passenger
exclude = exclude_list
return MyForm
form_class = get_form(('field1', 'field2'))
form = form_class()
UPDATE : Ich habe diesen Beitrag revisited und dachte, dass ich ein wenig mehr idiomatische Weise schreiben würde eine dynamische Klasse zu behandeln:
def PassengerForm(exclude_list, *args, **kwargs):
class MyPassengerForm(ModelForm):
class Meta:
model = Passenger
exclude = exclude_list
def __init__(self):
super(MyPassengerForm, self).__init__(*args, **kwargs)
return MyPassengerForm()
form = PassengerForm(('field1', 'field2'))
Andere Tipps
Eine andere Möglichkeit:
class PassengerInfoForm(ModelForm):
def __init__(self, *args, **kwargs):
exclude_list=kwargs.pop('exclude_list', '')
super(PassengerInfoForm, self).__init__(*args, **kwargs)
for field in exclude_list:
del self.fields[field]
class Meta:
model = Passenger
form = PassengerInfoForm(exclude_list=['field1', 'field2'])
ähnlicher Ansatz, etwas anderes Ziel (generic Modelform für beliebige Modelle):
from django.contrib.admin.widgets import AdminDateWidget
from django.forms import ModelForm
from django.db import models
def ModelFormFactory(some_model, *args, **kwargs):
"""
Create a ModelForm for some_model
"""
widdict = {}
# set some widgets for special fields
for field in some_model._meta.local_fields:
if type(field) is models.DateField:
widdict[field.name] = AdminDateWidget()
class MyModelForm(ModelForm): # I use my personal BaseModelForm as parent
class Meta:
model = some_model
widgets = widdict
return MyModelForm(*args, **kwargs)
Mit modelform_factory
( doc ):
from django.forms.models import modelform_factory
from testprogram.online_bookings.models import Passenger
exclude = ('field1', 'field2')
CustomForm = modelform_factory(model=Passenger, exclude=exclude) # generates ModelForm dynamically
custom_form = CustomForm(data=request.POST, ...) # form instance