Django中的外键和保存方法
我有以下型号:Django中的外键和保存方法,django,recursion,foreign-keys,save,Django,Recursion,Foreign Keys,Save,我有以下型号: 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(s
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)
这不起作用,即使在调用save()时为A.b和b.A分配了一个id,它仍然违反了A中的NOTNULL约束。
我在某个地方读到过,这是由于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)
好的,这取决于你先保存哪个对象,实际上在我的情况下,这两种情况都可能发生,但如果我能解决这个问题,那就太好了。。。这是正确的顺序,因为在保存时,我希望外键有效,因此必须先保存它。所以在我的例子中,我应该使用预保存信号,我尝试过,但它仍然会给我NOTNULL约束错误。