Django中的外键和保存方法

我有以下型号:

class A:
  b = ForeignKey('B')

class B:
  a = ForeignKey('A', null=True)

我有几种方法可以解码json对象并创建一个对象A和B的树.
假设我有一个我要保存的A类对象,我正在尝试写这样的东西

在A班:

def save(self, *args, **kwargs):
  self.b.save()
  super(A, self).save(*args, **kwargs)

在B:

def save(self, *args, **kwargs):
  if self.a:
    self.a.save()
  super(B, self).save(*args, **kwargs)

这不起作用,即使A.b和B.a在调用save()时被赋予id,它仍然违反了A中的not null约束.
我在某处看到这是由于ORM如何工作,以及如何以某种方式缓存对象.

提出的解决方案是做这样的事情:

a = A()
b = B()
b.save()
a.b = b
a.save()

但由于明显的递归原因,在我的情况下这是不合适的.因此,我能想到的唯一工作是为每个对象提供一个递归检索需要保存的每个对象的方法,然后执行for循环以按正确的顺序保存每个对象.我真的想避免这种情况,因为当然实际模型更复杂,并且每个类涉及两个以上的外键.

所以我想我的问题很简单:在这种情况下,有更好的方法或更常见的方法吗?

最佳答案 经过一些灵魂搜索,我发现这确实是一个缓存“问题”.我没有时间查看django代码以了解事情是如何工作的,所以如果有人有一些有趣的见解会很棒.

与此同时,我发现的解决方案是强制对象清除其缓存,如下所示:

def save(self, *args, **kwargs):
  self.b.save()
  self.b = self.b # yes ...
  super(A, self).save(*args, **kwargs)

这确实有效,但是对于记录,这里有一个小帮手可以在任何保存之前自动清除缓存:

def clear_cache(obj):
  map(lambda x: obj.__setattr__(x, obj.__getattribute__(x)), \ # force reassignment
    map(lambda x: re.match('_(.*)_cache', x).groups()[0], \    # get attribute name
    filter(lambda x: x.find('_cache') != -1, dir(obj))))       # get all attribute with cache

@receiver(pre_save)
def cache_callback(sender, instance, **kwargs):
  clear_cache(instance)
点赞