2009-08-26 12 views
1

AuditTrailのコードを変更して、ForeignKeyフィールドをコピーしないようにしましたが、関連フィールドをコピーします(つまり、私のデータベーステーブルに外部キーは必要ありません。監査モデル)。Django:AuditTrail&Lazy Relations

私はそうのように見えるcopy_field機能を書いている:

def copy_field(field): 
    while(isinstance(field, models.OneToOneField, models.ForeignKey)): 
     field = field.rel.get_related_field() 
    if isinstance(field, models.AutoField): 
     f = models.IntegerField() 
    else: 
     f = copy(field) 
    #...snip some adjusting of fs attributes... 
    return f 

AuditTrail属性を持つモデルは(class_prepared信号を介して)準備されている場合、このコードが実行されます。

ForeignKeyがまだ準備されていないモデルのフィールドに関連しているときしかし、これは問題に走る - get_related_field()コールは失敗します、field.rel.toは、関連するモデルの名前を含む文字列であるためではなく、モデルインスタンス。

私はこれを回避するために何をすべきか分かりません。フィールドのコピーを開始する前に、モデルの依存関係を判断して、準備が完了するまで待つ必要がありますか?これについての最善の方法についてのアイデア?

答えて

0
私は何をやってしまったことは、モデルが持っていたすべての依存関係を一覧表示した

(canoncialアプリ/名前のペアを決定することにより、これを決定するためにdjango.db.models.fields.relatedからいくつかのコードをコピー)し、すべてのモデルに耳を傾ける私のclass_preparedシグナルハンドラを修正するのではなく私の目標モデル。

ハンドラが依存リスト内のモデルを認識すると、そのリストからモデルが削除され、リストが空であるかどうかがチェックされます。そうであれば、監査モデルを作成しても構いません。重要なのは、モデルを作成する前にclass_preparedハンドラを切断することでした。そうでなければ、無限再帰が発生しました(あるいは、ハンドラをより具体的にgatedすることもできました)。

dependencies = [] 
    for field in cls._meta.local_fields: 
     while isinstance(field, (models.OneToOneField, models.ForeignKey)): 
      if isinstance(field.rel.to,basestring): 
       dependencies.append(get_canonical(cls,field.rel.to)) 
       break 
      else: 
       field = field.rel.get_related_field() 

    def _contribute(sender, **kwargs): 
     key = (sender._meta.app_label, sender.__name__) 
     if key in dependencies: 
      dependencies.remove(key) 
     if not dependencies: 
      models.signals.class_prepared.disconnect(_contribute) 
      model = create_audit_model(cls) 

    models.signals.class_prepared.connect(_contribute, weak=False) 
関連する問題