2011-06-01 63 views
7

我遇到了一个奇怪的问题,我希望这里有人能够阐明一些问题。ManyToMany字段在使用Django时未保存admin

运行super()后,我重写了模型的save()方法以将一些值添加到ManyToMany字段。我的问题是,当我在Django admin中保存时,这些值似乎会添加到关系中,但是会再次变为空。

但是,如果我从manage.py shell这样做,它没有问题。

我已经把两个打印语句放在那里,不管我是通过Django的管理员还是通过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丢弃。这与它如何处理表单有关?

+0

我不知道你的问题在哪里,但'self.holidays = self.copy_holidays_from.holidays.all()'看起来好多了,然后清理和迭代。 – DrTyrsa 2011-06-01 11:25:36

+0

谢谢你的提示,我不知道这是可能的。你可以在下面看到我做错了什么。 – 2011-06-01 15:47:26

回答

10

所以事实证明,上述不是实施它的正确方法。该代码属于StoreAdmin,通过重写model_save()。

这是我如何解决它:

class StoreAdmin(admin.ModelAdmin): 
    def save_model(self, request, obj, form, change): 
     if obj.copy_holidays_from: 
      form.cleaned_data['holidays'] = obj.copy_holidays_from.holidays.all() 

     super(StoreAdmin, self).save_model(request, obj, form, change) 
2

我今天也许碰到了这个相同的行为,是的,你是在假设它涉及到Django是如何处理的数据是正确的。

django admin将更改为ManyToMany字段与更改实际对象分开。 (请记住,m2m保存在不同的数据库表中)。

在我的情况下,如果我没有在管理站点的ManyToMany字段中选择任何内容,这将转化为对ManyToMany关系的clear()操作。您在save()方法中执行的所有操作都会立即被清除。我在post_save信号处理程序中做了同样的事情。

解决方案(对我来说)是将ManyToMany字段分隔成一个内联,因此在修改对象时它不会自动保存为空。

+0

你好Jyrsa,我有一个类似的问题与Django管理员。我们有一个m2m字段,有时会在保存页面的其余部分时清除。我不知道Django单独保存它。你能否联系我一些关于如何处理m2m的更多信息?你能否更具体地了解在什么情况下保存方法的动作被清除?谢谢! – iank 2014-10-22 15:42:46

+0

iank:此错误报告可能有所帮助: https://code.djangoproject.com/ticket/6707 – 2015-10-06 05:39:33

相关问题