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

时间:2010-02-10 01:46:13

标签: python django django-models merge

如何获取具有指向对象的ForeignKey的所有模型对象的列表? (类似于DELETE CASCADE之前Django管理员中的删除确认页面。)

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

感谢您的帮助!

9 个答案:

答案 0 :(得分:80)

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://docs.djangoproject.com/en/1.10/ref/models/meta/#django.db.models.options.Options.get_fields(请参阅_get_fields()来源中的反向)

答案 1 :(得分: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

这允许您创建django管理员显示的内容 - 要删除的相关对象。

答案 2 :(得分:7)

试一试。

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]

答案 3 :(得分:6)

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

答案 4 :(得分:5)

for link in links:
    objects = getattr(a, link).all()

适用于相关集,但不适用于ForeignKeys。由于相关管理器是动态创建的,因此查看类名比执行isinstance()

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

答案 5 :(得分:5)

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

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

print collector.data

答案 6 :(得分:4)

Django 1.9
get_all_related_objects()已弃用

#values from a standard normal density
eps <- 1e-1
points <- seq(-5,5, by = eps)    
x <- dnorm(points)    
y <- dnorm(points)

#padded values x, y with 0 to use fft function
xPad <- c(rep(0, length(y)),  x)    
yPad <- c(y, rep(0, length(x)))    
zPad <- fft(fft(xPad)*fft(yPad), inverse  = 'TRUE')/length(fft(xPad)*fft(yPad))    
plot(Re(zPad))    
max(Re(zPad))    
dnorm(0, sd = sqrt(2))

注意: RemovedInDjango110Warning:&#39; get_all_related_objects是一个已弃用的非官方API。您可以使用&#39; get_fields()&#39;

替换它

答案 7 :(得分:2)

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

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

答案 8 :(得分:1)

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