2011-09-24 1 views
10

他のインスタンスが参照するオブジェクトインスタンスを削除することを警告または防止したいと思います。これを行うには良い方法がありますか?Django:どのモデルがモデルを参照しているのかを確認するには

1つの方法は、参照対象を含むモデルのリストを取得してから逆引き参照を試みることです。そのモデルのリストを取得する方法はありますか?それとも良い方法がありますか?

コレクタの提案を検討している間、私はいくつかの関連情報を見つけ、外部キーとして参照先を持つクラス見つかっ以下の書いた:コレクトでコードを使用するための提案に基づいて

def find_related(cl, app): 
    """Find all classes which are related to the class cl (in app) by 
    having it as a foreign key.""" 

    from django.db import models 

    all_models = models.get_models() 
    ci_model = models.get_model(app, cl) 
    for a_model in all_models: 
     for f in a_model._meta.fields: 
      if isinstance(f, ForeignKey) and (f.rel.to == ci_model): 
       print a_model.__name__ 

を:

def find_related(instance): 
"""Find all objects which are related to instance.""" 

for related in instance._meta.get_all_related_objects(): 
    acc_name = related.get_accessor_name() 
    referers = getattr(instance, acc_name).all() 
    if referers: 
     print related 
+0

この問題を最終的な解決策で更新していただきありがとうございます。優れた仕事。 – Spike

+0

'find_related'は'(cl、app) 'を受け取り、' get_model'は '(app、cl)'を受け取ります。それは本当に混乱しています!また、誰かがこれを読んでいるなら、 'cl'と' app'は文字列です - オブジェクトを渡さないでください! – Casebash

答えて

3

Djangoには、Collectorクラスと呼ばれるものがあります。モデルの削除を実行するときにDjangoで使用されます。それはあなたが望むものとまったく同じように思えます。 collect()を呼び出すと、モデルグラフ内のオブジェクトへのすべての参照が見つかります。さらに、見つかったすべてのオブジェクトを削除する方法を提供します(delete()コール)。

私はこのクラスを自分で使ったことはないと言いましたが、私はそれが存在することを知っています。 APIはやや複雑ですが、Djangoの内部を少し掘り下げたい場合は、たくさんのコードを保存するかもしれません。

+0

それは有望に見えますが、私はCollector - CollectedObjectsの前身を持つ1.0を使用しています。これは、同様のメソッドを持っているようには見えません。 CollectedObjectsは、インスタンスによって参照されるオブジェクトを見つけるために(http://stackoverflow.com/questions/437166/duplicating-model-instances-and-the-related-objects-in-django-algorithm-for-r)で使用されます。削除される。 – Mitch

+0

(a)最新のバージョンにアップグレードできないという良い理由がありますし、(b)同様にコレクタを単独で使用することはできません。 – Marcin

+0

@Mitch:そうだね、ここでMarcinに同意します。アップグレードできない場合は、自分のコードのベースとして 'Collector.collect()'の実装を使うことができます。 Djangoコードは一般的にクリーンではありませんが、いくつかの分析の後ではまだ使用可能でなければなりません。 – julkiewicz

関連する問題