2008-11-17 25 views
22

güncelleyin. Bu kod, Meta sınıfındaki dışlama listesini güncelleştiriyor gibi görünse de, as_p(), as_ul(), vb. Çıktısı, güncellenmiş Meta dışlamayı yansıtmaz.Dinamik Dinamik benim görünümden bir ModelForm 'inline Meta sınıfını güncellemek umuyorum ModelForm Meta sınıf

Ben as_*() çağrıldığında ModelForm değil oluşturulduğunda html üretilir o zaman varsayalım. HTML güncellemesini zorlamak için bir yol var mı?

bunu yapmak için bu bile iyi yolu var mı? Sadece bu 'un çalışması gerektiğini varsaydım.

Düşünceler?

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 = [] 

cevap

55

Meta sınıf dinamik form tanımını oluşturmak için kullanılan - bu yüzden zaman sen ModelForm örneğini oluşturduk değil, alanlar zaten yeni nesnenin nitelikleri olarak eklenmiştir dışlama.

sadece olası her için listeyi hariç çoklu sınıf tanımları var olurdu yapmak normal bir şekilde. Ancak, formun kendisinin dinamik olmasını istiyorsanız, anında bir sınıf tanımı oluşturmanız gerekir. Bir şey gibi:

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() 

GÜNCELLEME: Sadece bu yazı revisited ve dinamik bir sınıf işlemek için biraz daha deyimsel yolu göndermek düşündüm:

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')) 
+2

+1: Dinamik bir şekilde sınıf yapı. Hasta. –

+0

Mükemmel. Teşekkürler! – ashchristopher

+0

harika bir örnek teşekkürler. model seti dinamik olarak da mümkün mü? form = getModelForm (Yolcu, ('field1', 'field2')) – jujule

12

Başka yolu:

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']) 
+0

biraz daha fazla çalışmayacak, ancak kesinlikle çalışacaktır –

+8

Muhtemelen yerine {} .pop() kullanmalısınız ayarladıktan sonra onu silerek. exclude_list = kwargs.pop ('exclude_list') Bir kod satırı kaydeder. * shrug * –

+0

olarak @JustinAbrahms, umarım ** kwargs.pop ('exclude_list', default_value) ** 'nı kullanabileceğinizi umuyoruz: exclude_list = kwargs.pop (' exclude_list ',' ') ' – suhailvs

3

Benzer yaklaşım, biraz farklı hedef (keyfi modeller için jenerik ModelForm):

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) 
2

kullanımı 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