如何使用未绑定表单的表单值

10 投票
3 回答
5437 浏览
提问于 2025-04-11 09:17

我有一个网页报告,使用Django的表单(新表单)来控制生成报告的查询字段,比如开始日期、结束日期等等。现在我遇到的问题是,页面应该能使用表单的初始值(未绑定状态)来工作,但我无法访问cleaned_data字段,除非我调用is_valid()。但是在未绑定的表单上,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'])

也就是说,绑定表单和未绑定表单之间没有一个通用的接口来获取表单的值。

有没有人看到更简单的方法来解决这个问题?

3 个回答

2

未绑定的意思是表单没有任何数据关联(无论是最开始的还是后面提供的),所以验证可能会失败。正如其他回答中提到的(还有你自己的结论),你需要提供初始值,并检查绑定的数据和初始值。

表单的使用场景是表单处理验证,因此在访问 cleaned_data 之前,你必须有一些数据来进行验证。

7

如果你在你的表单类里面加上这个方法:

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'))

撰写回答