【问题标题】:change a form value before validation in Django form在 Django 表单中验证之前更改表单值
【发布时间】:2013-09-03 06:22:54
【问题描述】:

我有一个 django 表单,在我的视图函数中我这样做:

search_packages_form = SearchPackagesForm( data = request.POST )

我想覆盖一个名为 price 的表单字段,该字段已被取消:

price = forms.ChoiceField( choices = PRICE_CHOICES, required = False,widget = forms.RadioSelect )

我想在调用search_packages_form.is_valid()之前覆盖表单域

我想过做:

search_packages_form.data['price'] = NEW_PRICE

但它不起作用。有什么想法吗?

【问题讨论】:

标签: python django django-forms


【解决方案1】:

form.is_valid() 贯穿您的表单(如果是 ModelForm 则为模型)clean 方法,返回 TrueFalse

如果您打算更改表单数据,您可以在一般的 clean 方法中或在字段级别进行,例如

class YourForm(DerivingClass):
    # regular stuff

    def clean_<ATTR>(self):
        # here
        return self.cleaned_data

    def clean(self):
        # or here
        return super(YourForm, self).clean()

【讨论】:

  • 对我不好。我不能这样做。它必须在验证之前运行,并且不能在 clean 函数中发生。我基本上想更改来自用户的数据。
  • 我认为您需要使用 javascript 来执行此操作。 .change.keyup
【解决方案2】:

可能不是 Django 方式,而是基于 https://stackoverflow.com/a/17304350/2730032 我猜想在验证之前更改表单值的最简单方法是执行以下操作:

def search_packages_view(request):
    if request.method == 'POST'
        updated_request = request.POST.copy()
        updated_request.update({'price': NEW_PRICE})
        search_packages_form = SearchPackagesForm(updated_request)
        if search_packages_form.is_valid():
             # You're all good

这可行,但如果有人有另一种看起来更符合 Django 的方法,或者没有的话,我会很感兴趣:然后解释一下原因。

【讨论】:

  • 您应该将updated_request 传递给表单而不是request.POST
  • @SirbitoX 当然,我编辑了答案。我不知道我是怎么犯这个错误的,谢谢你发现它。
【解决方案3】:

你想要的一个技巧就是这样做:

changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)

【讨论】:

  • 它不允许您访问表单中提交的实际数据。
【解决方案4】:

我的解决方案是建立在较早的提案之上的。这是一个可行的解决方案,可以在多种情况下使用。

@Milad Khodabandehloo 有一个棘手的解决方案来解决这个问题。

changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)

正如@The EasyLearn Academy 评论的那样:它不允许您访问以表单提交的实际数据。

这是因为 request.POST 是不可变的。

但问题有一个解决方案 - 只是需要更加棘手。

仅当对对象的引用足以满足特定原因时,此解决方案才有效。它使对象本身保持不变。

# write object to variable (data)
data = request.POST

# set to mutable
data._mutable = True

# modify the values in data 
data[modified_field] = new_value

# set mutable flag back (optional)
data._mutable = False

希望有用!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    相关资源
    最近更新 更多