我遇到了一个奇怪的问题,我希望有人在这里可能能够摆脱一些光。
在运行super()之后,我将覆盖模型的保存()方法,以便向ManyToMany-field添加一些值。我的问题是,当我在Django admin中保存时,值似乎被添加到关系中,但随后又是空的。
但是如果我从manage.py shell
做它,它工作没有问题。
我在里面放了两个print语句,不管我是通过Django admin还是通过shell运行它,它们都会产生完全相同的输出。
class Store(models.Model):
holidays = models.ManyToManyField(StoreHoliday, blank=True)
copy_holidays_from = models.ForeignKey('Store', blank=True, null=True)
def save(self):
print '==== BEFORE SAVE:', self.holidays.all()
super(Store, self).save()
self.copy_holidays()
print '==== AFTER SAVE:', self.holidays.all()
def copy_holidays(self):
if self.pk and self.copy_holidays_from:
self.holidays.clear()
for h in self.copy_holidays_from.holidays.all():
self.holidays.add( h )
字符串
下面是print
语句的输出:
==== BEFORE SAVE: []
==== AFTER SAVE: [<StoreHoliday: 10 Mar 2010, Chuck Norris birthday (Closed)>]
型
有没有人有任何建议,可能是什么原因造成的?
**编辑:**所有在save()中对m2m关系的手动更改似乎在通过管理界面保存时会被Django丢弃。这与它处理表单的方式有关吗?
6条答案
按热度按时间jq6vz3qz1#
因此,上面的方法并不是实现它的正确方法。通过重写model_保存(),代码属于StoreAdmin。
我是这样解决的:
字符串
2skhul332#
我今天可能遇到了同样的行为,是的,你假设这与django处理数据的方式有关是正确的。
django管理员将ManyToMany字段的更改与实际对象的更改分开。(请记住,m2m保存在不同的数据库表中)。
在我的例子中,如果我没有在管理站点的ManyToMany字段中选择任何内容,这将转换为ManyToMany关系上的clear()操作。你在保存()-方法中所做的一切都会立即被这个clear删除。与我在post_保存信号处理程序中所做的相同。
解决方案(对我来说)是将ManyToMany-field分隔成一个内联字段,这样在修改对象时它就不会自动保存为空。
nc1teljy3#
在Django2,1,4中,我的解决方案是使用保存_related()
字符串
xv8emn3q4#
对我来说,问题是管理员只保存最后选定的示例的许多领域(最后'假日'选定)。所以我必须重写保存_model方法,如下所示:
字符串
我花了很多时间在上面,其他的解决方案都不起作用,所以我希望它能有所帮助。
crcmnpdw5#
更新m2m的解决方案之一,沿着更新您的模型之一。
第一个月
在更新过程中,当您对m2m记录所做的更改没有保存时,即使您在模型之一的save方法中或在信号中进行了更改,您可以观察到的行为也只是因为m2m表单在主对象更新后重写了所有记录。
这就是为什么,一步一步:
1.主对象将更新。
1.您的代码(在保存方法或信号中)进行了更改(您可以查看它们,只需在ModelAdmin中放置断点):
字符串
有一个解决方案:通过transaction.on_commit使用m2m进行更改。transaction.on_commit将在提交事务时在form.save()之后进行更改。
不幸的是,这种解决方案的缺点是-您对m2m的更改将在单独的事务中执行。
mctunoxg6#
在我的情况下,它最终是因为我的数据库中的所有主键序列都不同步(..._id_seq表)。
在解决了这个问题(see this StackOverflow solution for that problem)之后,我的M2M模型再次开始保存。