簡體   English   中英

獲取所有相關的 Django 模型對象

[英]Get all related Django model objects

如何獲取具有指向對象的 ForeignKey 的所有模型對象的列表? (類似於 DELETE CASCADE 之前 Django 管理員中的刪除確認頁面)。

我正在嘗試提出一種合並數據庫中重復對象的通用方法。 基本上,我希望所有具有 ForeignKeys 指向對象“B”的對象都被更新為指向對象“A”,這樣我就可以刪除“B”而不會丟失任何重要的東西。

謝謝你的幫助!

姜戈 <= 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

我花了一段時間試圖弄清楚這一點,以便我可以在我的一個模型上實現一種“觀察者模式”。 希望它有幫助。

姜戈 1.8+

使用_meta.get_fields()https : _get_fields()也參見_get_fields()源中的反向)

@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 管理員顯示的內容 - 要刪除的相關對象。

試試這個。

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]

以下是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
for link in links:
    objects = getattr(a, link).all()

適用於相關集,但不適用於外鍵。 由於 RelatedManagers 是動態創建的,查看類名比執行 isinstance() 更容易

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

姜戈 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()”

這是獲取相關模型中的字段列表(僅限名稱)的另一種方法。

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() 不會返回該關系。 因此,如果您需要通用且健壯的方式來合並對象,我建議使用上面提到的收集器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM