2011-09-10 19 views
4

方法を保存します。私は、JSONオブジェクトをデコードし、オブジェクトAとBのツリーを作成し、いくつかの方法があります外部キーと、私は次のモデル持っジャンゴ

class A: 
    b = ForeignKey('B') 

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

を 私は型のオブジェクトがあるとし私は保存しておきたいことは、私はクラスAにこの

ような何かを書くことをしようとしている:Bで

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) 

これは、AbおよびBaは、それはまだ私は、これはORMの仕組みによるものであったことをどこかで読んだA. でNOT NULL制約に違反する)(SAVE呼び出し中にIDが割り当てられますにもかかわらず、動作しません。何らかの形でオブジェクトがどのようにキャッシュされているかを示します。

提案された解決策は、このような何かになった:

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

をしかし、再帰の明白な理由のために、それは私の場合には適切ではありません。ですから、私が考えることができる唯一の方法は、各オブジェクトに、保存する必要のあるすべてのオブジェクトを再帰的に取得するメソッドを提供し、その後、forループを実行して、それぞれを正しい順序で保存することです。私は本当にこれを避けたいと思います。もちろん、実際のモデルはより複雑で、クラスあたり2つ以上のクラスと複数の外部キーが必要です。

私の質問は単純です:このような状況では、より良い方法や進歩する方法がありますか?

答えて

2

これは確かにキャッシュの「問題」であることがわかりました。私は、実際にどのように動作するかを理解するために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) 
0

の前にの前に他のオブジェクトのセーブを行っていることには注意してください。スーパークラスの保存メソッドを呼び出すと、これはおそらくあなたが望むものの反対です。

また、クリーナーになる可能性があります。post-save signalsを使用してください。

+0

まず、どのオブジェクトを先に保存するかによって、実際には両方のケースが発生する可能性がありますが、この問題を解決できるかどうかはわかります。 – gobadiah

+0

Oupsがコメントを送信しました... これは正しい順序です.Aを保存すると、外部キーを有効にしたいので、最初に保存する必要があります。だから、私の場合、私は試してもそれはまだ私にnullでない拘束エラーを与える、保存前の信号を使用する必要があります。 – gobadiah

関連する問題