gpt4 book ai didi

django - Django 中的外键和保存方法

转载 作者:行者123 更新时间:2023-12-01 04:09:12 34 4
gpt4 key购买 nike

我有以下型号:

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)

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

这不起作用,即使 A.b 和 B.a 在调用 save() 时被分配了一个 id,它仍然违反了 A 中的非空约束。
我在某处读到这是由于 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)

这确实有效,但为了记录,这里有一个小 helper ,可以在任何保存之前自动清除缓存:
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)

关于django - Django 中的外键和保存方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7373772/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com