eri*_*kcw 84 python django merge django-models
如何获取具有指向对象的ForeignKey的所有模型对象的列表?(类似于DELETE CASCADE之前Django管理员中的删除确认页面).
我试图想出一种在数据库中合并重复对象的通用方法.基本上我希望所有具有ForeignKeys指向对象"B"的对象被更新为指向对象"A",这样我就可以删除"B"而不会丢失任何重要的东西.
谢谢你的帮助!
rob*_*les 81
这为您提供了所有相关对象的属性名称:
links = [rel.get_accessor_name() for rel in a._meta.get_all_related_objects()]
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用类似的东西来获取所有相关对象:
for link in links:
objects = getattr(a, link).all()
for object in objects:
# do something with related object instance
Run Code Online (Sandbox Code Playgroud)
我花了一些时间试图解决这个问题,所以我可以在我的一个模型上实现一种"观察者模式".希望它有用.
使用_meta.get_fields():https://docs.djangoproject.com/en/1.10/ref/models/meta/#django.db.models.options.Options.get_fields(在_get_fields()源代码中也见反向)
IMF*_*her 18
@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
Run Code Online (Sandbox Code Playgroud)
这允许您创建django管理员显示的内容 - 要删除的相关对象.
试一试.
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]
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
来自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
]
Run Code Online (Sandbox Code Playgroud)
因此,通过采用已批准的示例,我们将使用:
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
Run Code Online (Sandbox Code Playgroud)
小智 5
for link in links:
objects = getattr(a, link).all()
Run Code Online (Sandbox Code Playgroud)
适用于相关集,但不适用于ForeignKeys.由于相关管理器是动态创建的,因此查看类名比执行isinstance()更容易
objOrMgr = getattr(a, link)
if objOrMgr.__class__.__name__ == 'RelatedManager':
objects = objOrMgr.all()
else:
objects = [ objOrMgr ]
for object in objects:
# Do Stuff
Run Code Online (Sandbox Code Playgroud)
以下是django用于获取所有相关对象的内容
from django.db.models.deletion import Collector
collector = Collector(using="default")
collector.collect([a])
print collector.data
Run Code Online (Sandbox Code Playgroud)
Django 1.9
get_all_related_objects() 已被弃用
#Example:
user = User.objects.get(id=1)
print(user._meta.get_fields())
Run Code Online (Sandbox Code Playgroud)
注意: RemovedInDjango110Warning: 'get_all_related_objects 是一个已被弃用的非官方 API。您可以将其替换为“get_fields()”