动态ChoiceField无法通过表单

时间:2019-05-16 17:35:21

标签: python django django-forms

我有一个正在提供选择字典的表单,它正确填充了表单,但在表单提交时无效。尝试打印errors, non_field_errors时只有空白。当我重定向到表单时,现在选择字段由一个选择和先前提交的csrf令牌填充。

我尝试以不同的方式分配选择,例如self.fields['calendar'] = forms.ChoiceField(choices=choice_list)以不同的方式直接分配。 self.fields['calendar'].choices = choice_list,一个忽略验证的自定义验证器,并进行内联调试。

表单模型:

class CalendarSelectionForm(forms.Form):
    calendar = forms.ChoiceField(label="Calendar")

    def __init__(self, calendars=None, *args, **kwargs):
        super(CalendarSelectionForm, self).__init__(*args, **kwargs)
        choice_list = [(calendar_id, calendar_name) for calendar_id, calendar_name in calendars.items()]
        if calendars:
            self.fields['calendar'].choices = choice_list

查看:

    if request.method == "POST":
        print(request.POST)
        cal_sync_form = CalendarSelectionForm(request.POST)
        print("Non-field errors " + str(cal_sync_form.non_field_errors()))
        print("Reg form errors " + str(cal_sync_form.errors))
        # print("Field val " + str(cal_sync_form.calendar))
        print("Field data " + str(cal_sync_form.data))
        print("Field fields " + str(cal_sync_form.fields) + " Form is " + str(cal_sync_form.is_valid()))
        if cal_sync_form.is_valid():
            data = cal_sync_form.cleaned_data
            print(data)
            return render(request, 'management/gcal_sync_dashboard.html')
        else:
            return render(request, 'management/acct_select.html', {'form': cal_sync_form})

表单模板:

<form class="form-import" action="/manage/gcal/sync/" method="post" id = "">
    {% csrf_token %}
    {{ form.calendar }}
    {{ form.errors }}
    {{ form.non_field_errors }}
    <div class="push clearfix"></div>
    <div class="col-sm-6 no-pad push"><input class="btn btn-brand btn-little button filson push-half" type="submit" value="Select email"><i class="fa fa-plus"></i></input>
  </div>
</form>

目标是验证已过帐的表格,打印当前的打印报表

<QueryDict: {'csrfmiddlewaretoken': ['sJHE8JJAzmeS0nRjaYZg5KdMlevJiInYY0G4YFJeITH1cVjciIdR1Dq1N28loUIL'], 'calendar': ['email@email.io']}>
Non-field errors 
Reg form errors 
Field data {}
Field fields OrderedDict([('calendar', <django.forms.fields.ChoiceField object at 0x117323080>)]) Form is False

1 个答案:

答案 0 :(得分:1)

在您看来,您使用CalendarSelectionForm作为第一个 positional 参数调用request.POST构造函数。因此,这意味着您调用__init__函数,并且request.POST作为calendars参数传递。

您可以通过使用命名参数构造表单来解决此问题。此外,您将需要使用与使用GET请求呈现表单时相同的参数传递给calendars,因为否则选择本身就不匹配,并且用户可能选择了其中的一个选项。案例在POST请求期间可用。喜欢:

if request.method == 'POST':
    cal_sync_form = CalendarSelectionForm(calendars=my_calendars, data=request.POST)
    # ...

使用my_calendars与在GET情况下构造表单时传递的值相同。