好的,我一直在盯着这几个小时试图弄清楚发生了什么,但没有用。 我正在尝试使用'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,但显然我遗漏了一些东西。我非常感谢一些新鲜的眼睛告诉我我的错误。
由于
答案 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
这可能不是最好的方法,但是我发现从模型中获取绑定形式的唯一方法。我需要它,因为我想验证数据库中的当前数据。我创建了一个问题,因为我不认为这是最好的方法:
答案 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