Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

Django的Form无法保存ManyToManyField的解决办法



问题出现的场景是:django做的网站,有一个model包含了ForeignKey和ManyToManyField等字段,通过form并post数据保存时,发现其他字段都正常保存为期望值,而ManyToManyField在form做校验时能通过,但是值却没有保存下来。

发现问题出现的原因是:form.save(commit=False)这里commit是false,也就是并没有立马存进数据库,而ManyToMany无法对一个还不存在的数据做关联。

解决办法是:

1. 要么form在save时不要指明commit为false,可以用默认的commit为true。

2. 要么form在save时指明了commit为false,在对应的model数据存入后,调用form.save_m2m()来存入ManyToMany的数据。

如果出现了错误提示:"object has no attribute 'save_m2m'". 这时检查一下前面的代码中是否存在form.save()。

可以参考django的官方说明(django model form save):

This save() method accepts an optional commit keyword argument, which accepts either True or False.
If you call save() with commit=False, then it will return an object that hasn’t yet been saved to the database. 
In this case, it’s up to you to call save() on the resulting model instance. 
This is useful if you want to do custom processing on the object before saving it, or if you want to use one of the specialized model saving options. commit is True by default.

Another side effect of using commit=False is seen when your model has a many-to-many relation with another model. 
If your model has a many-to-many relation and you specify commit=False when you save a form, Django cannot immediately save the form data for the many-to-many relation. 
This is because it isn’t possible to save many-to-many data for an instance until the instance exists in the database.

To work around this problem, every time you save a form using commit=False, Django adds a save_m2m() method to your ModelForm subclass. 
After you’ve manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data. 

 

下一篇:  用Django做一个简单的记账网站(六)处理Ajax请求
上一篇:  关于Python中的GIL的限制和注意点

共有0条评论

添加评论

暂无评论