【问题标题】:Clearing Django form fields on form validation error?在表单验证错误中清除 Django 表单字段?
【发布时间】:2010-03-01 03:27:48
【问题描述】:

我有一个允许用户更改密码的 Django 表单。我发现表单错误使字段中仍然包含 * 的数据令人困惑。

我尝试了几种删除 form.data 的方法,但我不断收到This QueryDict instance is immutable 异常消息。

是否有适当的方法来清除 clean() 中的单个表单字段或整个表单数据集?

【问题讨论】:

标签: python django django-forms


【解决方案1】:

关于不可变 QueryDict 错误,您的问题几乎可以肯定是您创建了这样的表单实例:

form = MyForm(request.POST)

这意味着 form.data 从 POST 变量创建的实际 QueryDict。由于请求本身是不可变的,因此当您尝试更改其中的任何内容时会出现错误。在这种情况下,说

form.data['field'] = None

完全一样
request.POST['field'] = None

为了得到一个可以修改的表单,你想这样构造它:

form = MyForm(request.POST.copy())

【讨论】:

  • 请注意,对于表单中的文件字段或图像字段,您必须以相同的方式设置 form.files 而不是 form.data。
【解决方案2】:

有人向我展示了如何做到这一点。这种方法对我有用:

post_vars = {}  
post_vars.update(request.POST)  
form = MyForm(post_vars, auto_id='my-form-%s')  
form.data['fieldname'] = ''  
form.data['fieldname2'] = ''

【讨论】:

  • 这行得通,但它不是很干净,因为您是在视图级别进行的。 IMO,您应该将默认登录表单子类化并按照 Igor 的建议替换 clean() 方法。也就是说,首先验证它们是否正确;清除相关的 self.data 字段,最后引发 ValidationError。
  • 你能详细说明一下吗?我仍然收到不可变的 querydict 错误。
  • post_vars.update(request.POST) 是一种不太干净的 dict(request.POST) 方式。在任何一种情况下,您没有用 form.data 覆盖的表单提交的值最终会在呈现的表单中显示为 u' '(但不确定为什么会发生这种情况)。按照@Ian 的建议使用 request.POST.copy() 就像一个魅力。
【解决方案3】:

如果您需要使用表单中的多个字段进行额外验证,请覆盖 .clean() 方法。但如果只针对一个字段,则可以创建一个 clean_field_name() 方法。

http://docs.djangoproject.com/en/1.1/ref/forms/validation/#ref-forms-validation

【讨论】:

  • Igor,我知道如何验证表单。问题是当验证失败时,我希望表单字段返回空,而不是用户提供的数据。
  • Igor 是在正确的轨道上,不过,ChrisW。 IMO,您应该使用 clean() 方法来验证两个密码 - 如果它们不正确,请在引发验证错误之前清除 self.data 字段。
  • 谁能详细说明一下。当我尝试 self.data['field'] = None 在引发validationError之前没有任何反应,甚至没有引发验证错误。
【解决方案4】:

我刚刚重新创建了表单。

试试看:

form = AwesomeForm()

然后渲染它。

【讨论】:

    【解决方案5】:

    Django 有一个小部件可以做到这一点: https://docs.djangoproject.com/en/1.8/ref/forms/widgets/#passwordinput

    现在,如果您不使用密码,您可以执行以下操作:

    class NonceInput(Input):
        """
        Hidden Input that resets its value after invalid data is entered
        """
        input_type = 'hidden'
        is_hidden = True
    
        def render(self, name, value, attrs=None):
            return super(NonceInput, self).render(name, None, attrs)
    

    当然,你可以让任何 django 小部件忘记它的值,只需覆盖它的渲染方法(而不是我在 super 调用中传递的值 None。)

    【讨论】:

      【解决方案6】:

      您不能在验证期间从表单的clean_data 中删除密码数据吗?

      the Django docs for custom validation(尤其是第二段代码)。

      【讨论】:

        【解决方案7】:

        我猜你需要使用 JavaScript 来隐藏或删除容器中的文本。

        【讨论】:

        • 当然必须有一种方法可以在服务器端执行此操作...取决于客户端 JavaScript 是一种非常混乱的方法来完成此操作。
        猜你喜欢
        • 1970-01-01
        • 2013-05-26
        • 2013-08-30
        • 1970-01-01
        • 2017-08-06
        • 2017-06-19
        • 1970-01-01
        • 2020-10-15
        • 2021-01-01
        相关资源
        最近更新 更多