由于BD设计依赖于一个值,数据存储在不同的单元格中,我必须动态添加表单字段。我在想这个:
class EditFlatForm(BaseModelForm):
on_sale = forms.BooleanField(required=False)
on_rent = forms.BooleanField(required=False)
class Meta:
model = Flat
fields = ('title', 'flat_category', 'description')
...
def __init__(self, *args, **kwargs):
super(EditFlatForm, self).__init__(*args,**kwargs)
flat_properties = FlatProperty.objects.all()
for p in flat_properties:
if p.type_value == 1:
# Text
setattr(self, p.title, forms.CharField(label=p.human_title, required=False))
elif p.type_value == 2:
# Number
setattr(self, p.title, forms.IntegerField(label=p.human_title, required=False))
else:
# Boolean
setattr(self, p.title, forms.BooleanField(label=p.human_title, required=False))
但是这些字段没有被添加,我缺少什么?
答案 0 :(得分:6)
我建议使用type
即时创建表单。因此,您需要创建一个函数,该函数将生成您希望在表单中包含的所有字段的列表,然后使用它们生成表单,如下所示:
def get_form_class(): flat_properties = FlatProperty.objects.all() form_fields = {} for p in flat_properties: if p.type_value == 1: form_fields['field_{0}'.format(p.id)] = django.forms.CharField(...) elif p.type_value == 2: form_fields['field_{0}'.format(p.id)] = django.forms.IntegerField(...) else: form_fields['field_{0}'.format(p.id)] = django.forms.BooleanField(...) # ok now form_fields has all the fields for our form return type('DynamicForm', (django.forms.Form,), form_fields )
现在,您可以在任何地方使用get_form_class
,例如
form_class = get_form_class()
form = form_class(request.GET)
if form.is_valid() # etc
有关详细信息,您可以查看我使用django创建动态表单的帖子: http://spapas.github.io/2013/12/24/django-dynamic-forms/
更新以解决OP的评论(但后来如何利用ModelForm提供的所有功能?):您可以从ModelForm
继承您的动态表单。或者,更好的是,您可以创建一个ModelForm
后代的类,并定义所有必需的方法和属性(如clean
,__init__
,Meta
等)。然后通过将type
调用更改为type('DynamicForm', (CustomForm,), form_fields )
来继承该类;
答案 1 :(得分:3)
假设p.title
是一个字符串变量,那么这应该有效:
if p.type_value == 1:
# Text
self.fields[p.title] = forms.CharField(label=p.human_title, required=False))