【问题标题】:Django ModelForm fails validation with no errorsDjango ModelForm 验证失败且没有错误
【发布时间】:2011-04-21 15:39:02
【问题描述】:

好的,我已经盯着这个看了好几个小时,试图弄清楚发生了什么,但无济于事。 我正在尝试使用“instance”关键字创建一个 ModelForm 以将其传递给现有模型实例,然后保存它。 这是 ModelForm(在我试图找出这个问题的原因时,从原来的版本中删除了很多):

class TempRuleFieldForm(ModelForm):
    class Meta:
        model = RuleField

这是我正在运行的代码:

>>> m = RuleField.objects.get(pk=1)
>>> f = TempRuleFieldForm(instance=m)
>>> f.is_valid()
False

模型对象(上面的m)是有效的,它保存得很好,但表单不会验证。现在,据我所知,此代码与此处的 Django 文档示例相同:http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method,但显然我遗漏了一些东西。我将非常感谢一些新鲜的眼睛来告诉我我做错了什么。

谢谢

【问题讨论】:

  • f.errors 打印出什么?

标签: django validation modelform


【解决方案1】:

对于 OP 来说不是一个解决方案,但这是我遇到的一个问题,特别是在 ModelForms 上运行单元测试时,继续绑定表单然后还定义一个具有相同数据的实例是一件令人讨厌的事情。我创建了一个小的帮助函数来简化其他人可能会觉得有用的事情——我只是将它用于测试目的,并且会谨慎地将其部署到其他任何地方而无需进行重大调整(如果有的话)

def testing_model_form(instance, model_form_class):
"""
A function that creates instances ModelForms useful for testing, basically takes an instance as an argument and will take care
of automatic binding of the form so it can be validated and errors checked
"""
fields = model_form_class.Meta.fields

data_dict = {}
for field in fields:
    if hasattr(instance, field):
        # The field is present on the model instance
        data_dict[field] = getattr(instance, field)
x = model_form_class(data=data_dict)
x.instance = instance
return x

【讨论】:

    【解决方案2】:

    这不是针对 OP 的解决方案,而是针对帖子标题的解决方案,这在 Google 中是相当高的。所以无论如何我都会发布它,来自here

    如果您已经使用 request.POST or None 将 request.POST 发送给您的表单,但它仍然无效且没有错误,请检查是否有任何重定向正在进行。重定向会丢失您的 POST 数据,并且您的表单将无效且没有错误,因为它未绑定。

    【讨论】:

      【解决方案3】:

      如果你还想验证数据库中的对象,你可以先序列化它,然后用它创建表单。

      from django.utils import simplejson
      from django.core.serializers import serialize
      
      (...)
      
      fields_dict = simplejson.loads(serialize('json', [obj]))[0]['fields']
      form = forms.MyForm(fields_dict)
      if form.is_valid
      

      这可能不是最好的方法,而是我发现的唯一一种从模型中获取绑定形式的方法。我需要它,因为我想验证数据库中的当前数据。我提出一个问题,因为我认为这不是最好的方法:

      Transform an unbound form to a bound one?

      【讨论】:

      • 我错过了整个“将数据绑定到表单”的事情,这就是您通过序列化实现的目标。我相信 Django 的 django.forms.models.model_to_dict 会比所说的序列化更好 - 请参阅我对您问题的回答:link
      【解决方案4】:

      请注意,您的链接不会调用f.is_valid(),它只是直接保存。这可能有点误导。

      关键是,仅使用instance 参数但没有data 实例化表单并将其绑定到数据,因此该表单无效。你会看到f.is_bound 是假的。

      在幕后,instance 与传递initial 数据实际上是一样的,正如文档说明,它最初仅用于显示数据,不用于保存。您可能会从阅读notes on bound and unbound forms 中受益。

      【讨论】:

      • +1。 “实例并不意味着绑定”:这是正确的推理。
      • 只是为了澄清,我使用 f.is_valid() 的原因只是为了让问题更简洁。使用 f.save() 失败,并在 clean_data 字段上出现 AttributeError,该字段在表单验证之前不存在。因此,即使我在我发布的链接中使用代码完全(使用 f.save() 而不是 f.is_valid()),它仍然失败。
      • 有人可以建议如何将数据从实例转换为绑定到表单的数据...因为它似乎并不清楚
      • @OlegTarasenko 你应该问一个新问题,准确解释你在做什么以及出了什么问题。
      • @DanielRoseman 我同意。但在这种情况下,我想问是否有办法让 form.save() 在上面的示例中工作
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      • 1970-01-01
      • 2013-10-20
      • 2013-01-17
      • 1970-01-01
      相关资源
      最近更新 更多