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