Динамическое добавление полей формы в форму 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 )
!