Django ModelForm验证失败,没有错误

时间:2010-10-06 05:48:50

标签: django validation modelform

好的,我一直在盯着这几个小时试图弄清楚发生了什么,但没有用。 我正在尝试使用'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,但显然我遗漏了一些东西。我非常感谢一些新鲜的眼睛告诉我我的错误。

由于

4 个答案:

答案 0 :(得分:21)

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

关键是实例化仅包含instance参数但没有data的表单将其绑定到数据,因此表单无效。您会看到f.is_bound为假。

在幕后,instance实际上与传递initial数据相同,因为文档说明仅用于初始显示数据而不用于保存。您可能会因阅读notes on bound and unbound forms而受益。

答案 1 :(得分: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?

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

并不是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