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 = []
War es hilfreich?

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top