如何使用未绑定表单中的表单值
时间:2020-03-05 18:56:49 来源:igfitidea点击:
我有一个Web报告,该报告使用Django表单(新表单)作为用于控制用于生成报告的查询(开始日期,结束日期等)的字段。我遇到的问题是页面应该使用表单的初始值(未绑定)工作,但是除非调用is_valid(),否则我将无法访问cleaned_data字段。但是is_valid()在未绑定的表单上总是失败。
似乎Django的表单是用编辑数据的用例设计的,因此,除了显示HTML之外,未绑定的表单对其他任何事情都没有真正的用处。
例如,如果我有:
if request.method == 'GET': form = MyForm() else: form = MyForm(request.method.POST) if form.is_valid(): do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
如果这是一个GET(因为它是未绑定的),并且如果我这样做,则is_valid()将失败:
if request.method == 'GET': form = MyForm() do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date']) else: form = MyForm(request.method.POST) if form.is_valid(): do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
第一次调用do_query会触发form.cleaned_data上的异常,该字段不是有效字段,因为尚未调用is_valid()。看来我必须做类似的事情:
if request.method == 'GET': form = MyForm() do_query(form['start_date'].field.initial, form['end_date'].field.initial) else: form = MyForm(request.method.POST) if form.is_valid(): do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
也就是说,在绑定的表单和未绑定的表单之间没有通用的接口来检索表单的值。
有没有人看到一种更清洁的方式来做到这一点?
解决方案
回答
我们可以将初始值字典传递给表单:
if request.method == "GET": # calculate my_start_date and my_end_date here... form = MyForm( { 'start_date': my_start_date, 'end_date': my_end_date} ) ...
请参阅正式的表单API文档,其中演示了这一点。
编辑:根据其他用户的答案,也许这是最干净的解决方案:
if request.method == "GET": form = MyForm() form['start_date'] = form['start_date'].field.initial form['end_date'] = form['end_date'].field.initial else: form = MyForm(request.method.POST) if form.is_valid(): do_query(form.cleaned_data['start_date'], form.cleaned_data['end_date'])
我还没有尝试过;有人可以确认这有效吗?我认为这比创建新方法更好,因为这种方法不需要其他代码(可能不是我们编写的)就可以知道新的"魔术"访问器。
回答
如果将此方法添加到表单类中:
def get_cleaned_or_initial(self, fieldname): if hasattr(self, 'cleaned_data'): return self.cleaned_data.get(fieldname) else: return self[fieldname].field.initial
然后,我们可以将代码重新编写为:
if request.method == 'GET': form = MyForm() else: form = MyForm(request.method.POST) form.is_valid() do_query(form.get_cleaned_or_initial('start_date'), form.get_cleaned_or_initial('end_date'))
回答
未绑定意味着没有与表单关联的数据(初始数据或者以后提供的数据),因此验证可能会失败。如其他答案(以及我们自己的结论)中所述,我们必须提供初始值并检查绑定数据和初始值。
表单的用例是表单处理和验证,因此在访问cleaned_data
之前,我们必须有一些数据要进行验证。