如何使用动态更新的Choicefield验证表单集?

时间:2018-08-23 15:34:58

标签: django django-forms

我正在使用formset_factory管理页面上的几个相同表格。在每种形式中,都有一对链接的下拉列表。 DropdownA具有一个onchange事件,该事件请求dropdownB(AJAX)的选项。一切正常,但是当我通过POST请求提交表单时,它们都未通过forms.is_valid()检查。打印提交的表单集的错误揭示了原因:

[{'DropdownB ': ['Select a valid choice. Like is not one of the available choices.']}, {'DropdownB ': ['Select a valid choice. < is not one of the available choices.']}]

有两个错误,每个表格一个。他们俩都抱怨为DropdownB发送的选择不是可用的选择之一(分别为'Like'和'<')。

现在,因为我只想基于DropdownA选择的内容来填充DropdownB,所以我特意定义了0个选择的DropdownB(一个选择域)。

DropdownB = ()
DropdownB = forms.ChoiceField(choices=op_choices, required=False)

我如何根据DropdownA的值向服务器指定哪些有效选择?

我试图在上面的摘要中简化此问题,但是如果您需要表单的完整代码,则可以执行以下操作:

class UnifiedSingleSearchBar(forms.Form):
# Dict to categorize field types
type_dict = {
    'DateField': 'Numeric',
    'DateTimeField': 'Numeric',
    'AutoField': 'Numeric',
    'CharField': 'String',
    'BooleanField': 'Bool',
}
operation_dict = {'Numeric':
                      (
                          ('>', '>'),
                          ('>=', '>='),
                          ('<', '<'),
                          ('<=', '<='),
                          ('=', '='),
                          ('>-<', 'Between'),
                          ('0', 'IS null'),
                          ('1', 'IS NOT null'),
                      ),
                    'String':
                        (
                            ('Like', 'Like'),
                            ('Is', 'Is')
                        ),
                    'Bool':
                        (
                            ('True', 'True'),
                            ('False', 'False')
                        )
                  }
searchabel_field_choices = ()
# To create the "field" dropdown, we loop through every field in the model and note its type.
for field in Mymodel._meta.fields:
    tuple = (
        (field.name, field.name),  # signifies a nested tuple
    )
    searchabel_field_choices = searchabel_field_choices + tuple
searchabel_field_choices = searchabel_field_choices + (('', '--------'),)
shared_attrs = {
    'autocomplete': 'off',
    'class': 'form-control datetimepicker-input',
}
searchable_field = forms.ChoiceField(choices=searchabel_field_choices, required=False)
op_choices = ()  # Should always start with an empty operations list since field has not yet been chosen
operation = forms.ChoiceField(choices=op_choices, required=False)

# 2 is usually only ever used if a range is being specified
# Numeric
date1 = forms.DateField(required=False, widget=DatePicker(attrs=shared_attrs))
date2 = forms.DateField(required=False, widget=DatePicker(attrs=shared_attrs))
datetime1 = forms.DateTimeField(required=False, widget=DateTimePicker(attrs=shared_attrs))
datetime2 = forms.DateTimeField(required=False, widget=DateTimePicker(attrs=shared_attrs))
integer = forms.IntegerField(required=False)
# Bool
bool = forms.BooleanField(required=False)
# String
string = forms.CharField(required=False)

1 个答案:

答案 0 :(得分:0)

答案Here解决了我的问题。每次循环访问表单集中的表单时,都会读取请求中为该表单指定的DropdownA中的值,并使用该信息为该特定表单再次设置DropdownB的有效选择。

相关问题