如何获得所有具有ForeignKey指向对象的模型对象的列表?(有点像Django管理员中DELETE CASCADE之前的Delete确认页面)。
我试图提出一种合并数据库中重复对象的通用方法。基本上,我希望所有具有ForeignKeys指向对象“ B”的对象都被更新为指向对象“ A”,这样我就可以删除“ B”而不会丢失任何重要内容。
谢谢你的帮助!
Answers:
这为您提供了所有相关对象的属性名称:
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
我花了一段时间试图弄清楚这一点,以便可以在自己的模型中实现一种“观察者模式”。希望对您有所帮助。
使用_meta.get_fields()
:https : //docs.djangoproject.com/en/1.10/ref/models/meta/#django.db.models.options.Options.get_fields(另请参见_get_fields()
源中的反向)
all()
零件将在上失败OneToOneField
。您必须以某种方式检测到它。
_meta.get_fields()
:docs.djangoproject.com/en/1.10/ref/models/meta/...(见reverse
的_get_fields()
人士还)
_meta.get_fields()
技巧上,这对我来说是解决方案的一部分:(已links = [field.get_accessor_name() for field in obj._meta.get_fields() if issubclass(type(field), ForeignObjectRel)]
考虑from django.db.models.fields.related import ForeignObjectRel
)
@digitalPBK已经关闭...这可能是您在寻找使用Django内置东西的东西,该东西在Django管理员中用于在删除期间显示相关对象
from django.contrib.admin.utils import NestedObjects
collector = NestedObjects(using="default") #database name
collector.collect([objective]) #list of objects. single one won't do
print(collector.data)
这使您可以创建Django管理员显示的内容-要删除的相关对象。
Collector
不使用(从第1行导入)?
以下是django用于获取所有相关对象的内容
from django.db.models.deletion import Collector
collector = Collector(using="default")
collector.collect([a])
print collector.data
links = [rel.get_accessor_name() for rel in a._meta.get_all_related_objects()]
然后,您可以使用类似这样的方法来获取所有相关对象:
for link in links:
objects = getattr(a, link.name).all()
for object in objects:
# do something with related object instance
从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
python for link in links: objects = getattr(a, link.name).all() for object in objects:
for link in links:
objects = getattr(a, link).all()
适用于相关集,但不适用于ForeignKeys。由于RelatedManager是动态创建的,因此查看类名比执行isinstance()容易。
objOrMgr = getattr(a, link)
if objOrMgr.__class__.__name__ == 'RelatedManager':
objects = objOrMgr.all()
else:
objects = [ objOrMgr ]
for object in objects:
# Do Stuff
Django 1.9
get_all_related_objects()已弃用
#Example:
user = User.objects.get(id=1)
print(user._meta.get_fields())
注意: RemovedInDjango110警告:'get_all_related_objects是已被弃用的非官方API。您可能可以将其替换为“ get_fields()”
不幸的是,user._meta.get_fields()仅返回可从用户访问的关系,但是,您可能具有一些相关的对象,该对象使用related_name ='+'。在这种情况下,user._meta.get_fields()不会返回该关系。因此,如果您需要通用且健壮的方式来合并对象,建议您使用上面提到的收集器。