Динамическое добавление полей формы в форму django
из-за дизайна 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))
но поля не добавляются, что мне не хватает?
2 ответов
предполагая, что p.title является строковой переменной, тогда это должно работать:
if p.type_value == 1:
# Text
self.fields[p.title] = forms.CharField(label=p.human_title, required=False))
Я рекомендую создать форму с помощью 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/
обновление в адрес ОП комментарий (но тогда как получить все вещи ModelForm содержит?): Вы можете наследовать свою динамическую форму от ModelForm. Или, еще лучше, вы можете создать класс, который является потомком ModelForm и определяет все необходимые методы и атрибуты (например,clean, __init__, Meta и т. д.). Тогда просто наследуйте от этого класса, изменив type вызов type('DynamicForm', (CustomForm,), form_fields ) !