2011-09-24 42 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

相关问题