我希望从我的视图中动态更新ModelForm的内联Meta类。虽然此代码似乎更新了Meta类中的排除列表,但as_p()
,as_ul()
等的输出并未反映更新的Meta排除。
我假设在创建ModelForm时不是在调用as_*()
时生成html。有没有办法强制更新HTML?
这是最好的方法吗?我只是假设这个应该工作。
思想?
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 = []
答案 0 :(得分:56)
Meta类用于动态构造表单定义 - 因此,当您创建ModelForm实例时,不在排除中的字段已添加为新对象的属性。
执行此操作的常规方法是为每个可能的排除列表提供多个类定义。但是如果你希望表单本身是动态的,你必须动态创建一个类定义。类似的东西:
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()
更新:我刚刚重访这篇文章,并认为我会发布一些更惯用的方式来处理动态类:
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'))
答案 1 :(得分:13)
另一种方式:
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'])
答案 2 :(得分:3)
类似的方法,有些不同的目标(任意模型的通用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)
答案 3 :(得分:3)
使用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