2011-09-24 64 views
10

我想警告或阻止用戶刪除其他實例引用的對象實例。有沒有一個很好的方法來做到這一點?Django:我如何才能找到哪個模型引用模型

一種方法是獲取包含指示對象的模型列表,然後嘗試對它們進行反向查找。有沒有辦法獲得這個模型列表?或者,還有更好的方法?

當調查收集的建議,我發現了一些相關的信息,並寫了發現其中有所指的外鍵的類如下:

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

這看起來很有前途,但我使用1.0,它只有Collector - CollectedObjects的前身,它看起來不像它有類似的方法。 CollectedObjects用於(http://stackoverflow.com/questions/437166/duplicating-model-instances-and-their-related-objects-in-django-algorithm-for-r)查找實例引用的對象被刪除。 – Mitch

+0

我們可以假設:(a)有很好的理由不能升級到更新的版本;(b)同樣你不能單獨使用收集器? – Marcin

+0

@Mitch:是的,我同意Marcin的觀點,如果你不能升級,你總是可以嘗試使用'Collector.collect()'實現作爲你自己代碼的基礎。一般而言,Django代碼遠非乾淨,但經過一些分析後,它應該仍然可用。 – julkiewicz