获取所有相关的Django模型对象

我怎样才能得到一个所有的模型对象有一个ForeignKey指向一个对象的列表? (类似DELETE CASCADE之前的Djangopipe理员中的删除确认页面)。

我试图想出一个在数据库中合并重复对象的通用方法。 基本上我希望所有具有ForeignKeys指向对象“B”的对象都被更新为指向对象“A”,这样我就可以删除“B”而不会丢失任何重要的东西。

谢谢你的帮助!

Django <= 1.7

这给你所有相关对象的属性名称:

 links = [rel.get_accessor_name() for rel in a._meta.get_all_related_objects()] 

然后你可以使用这样的东西来获得所有相关的对象:

 for link in links: objects = getattr(a, link).all() for object in objects: # do something with related object instance 

我花了一段时间试图弄清楚这一点,所以我可以在我的一个模型上实现一种“观察者模式”。 希望这是有帮助的。

Django 1.8+

使用_meta.get_fields() : https : _meta.get_fields()请参阅_get_fields()源中的反向)

@ digitalPBK是接近…这可能是你正在寻找使用Django内置的东西

 from django.db.models.deletion import Collector from django.contrib.admin.util import NestedObjects collector = NestedObjects(using="default") #database name collector.collect([objective]) #list of objects. single one won't do print collector.data 

这允许您创builddjango admin显示的内容 – 要删除的相关对象。

试试这个。

 class A(models.Model): def get_foreign_fields(self): return [getattr(self, f.name) for f in self._meta.fields if type(f) == models.fields.related.ForeignKey] 
 for link in links: objects = getattr(a, link).all() 

适用于相关套件,但不适用于ForeignKeys。 由于RelatedManagers是dynamic创build的,因此查看类名比执行isinstance()更容易

 objOrMgr = getattr(a, link) if objOrMgr.__class__.__name__ == 'RelatedManager': objects = objOrMgr.all() else: objects = [ objOrMgr ] for object in objects: # Do Stuff 

以下是django用来获取所有相关对象的内容

 from django.db.models.deletion import Collector collector = Collector(using="default") collector.collect([a]) print collector.data 

Django 1.9
get_all_related_objects()已被弃用

 #Example: user = User.objects.get(id=1) print(user._meta.get_fields()) 

注意: RemovedInDjango110Warning:'get_all_related_objects是一个非官方的API已被弃用。 你可以用'get_fields()'replace它

links = [rel.get_accessor_name()for rel in a._meta.get_all_related_objects()]然后,您可以使用这样的东西来获取所有相关的对象:

链接的链接:objects = getattr(a,link.name).all()对象中的对象:#做一些相关的对象实例

从Django 1.10官方文档:

MyModel._meta.get_all_related_objects()变成:

 [ f for f in MyModel._meta.get_fields() if (f.one_to_many or f.one_to_one) and f.auto_created and not f.concrete ] 

所以通过采用这个认可的例子,我们可以使用

 links = [f for f in MyModel._meta.get_fields() if (f.one_to_many or f.one_to_one) and f.auto_created and not f.concrete ] for link in links: objects = getattr(a, link.name).all() for object in objects: # do something with related object instance 

这是另一种获取相关模型中的字段列表(仅限名称)的方法。

 def get_related_model_fields(model): fields=[] related_models = model._meta.get_all_related_objects() for r in related_models: fields.extend(r.opts.get_all_field_names()) return fields 

不幸的是,user._meta.get_fields()只返回用户可访问的关系,但是,你可能有一些相关的对象,它使用related_name ='+'。 在这种情况下,关系不会被user._meta.get_fields()返回。 因此,如果你需要通用和健壮的方式来合并对象,我build议使用上面提到的收集器。