【问题标题】:django-contenttypes - List All Generic Relations for Modeldjango-contenttypes - 列出模型的所有通用关系
【发布时间】:2012-05-22 13:32:25
【问题描述】:

我想反思一个模型并列出它所有的向后通用关系。

我的模型如下所示:

class Service(models.Model):
    host = models.ForeignKey(Host)

    statuses = generic.GenericRelation(Status)

Status 对象如下所示:

class Status(TrackedModel):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()

    class Meta:
        verbose_name_plural = 'statuses'

我想以编程方式了解statuses 是服务模型的通用关系。这可能吗? Status._meta.fields 不显示statuses,但Status._meta.get_all_field_names() 显示,只是它还显示了其他不需要的东西。

我认为这可能是一个可能的解决方案,但对我来说似乎真的很乱。我很想听听更好的。

from django.db.models.fields import FieldDoesNotExist
from django.contrib.contenttypes import generic

generic_relations = []
for field_name in Service._meta.get_all_field_names():
    try:
        field = Service._meta.get_field(field_name)
    except FieldDoesNotExist:
        continue

    if isinstance(field, generic.GenericRelation):
        generic_relations.append(field)

谢谢!

【问题讨论】:

    标签: python django django-contenttypes


    【解决方案1】:

    GenericRelation 的工作方式与 ManyToManyField 类似。你可以在Service._meta.many_to_many找到它:

    filter(lambda f:isinstance(f, generic.GenericRelation), Service._meta.many_to_many)
    

    【讨论】:

    • 这适用于 1.5,但不再适用于 1.6。这可能是一个错误,因为我们可以使用get_field_by_name 获取字段,但不能使用get_field
    • 这已经过时了,很遗憾。它现在似乎只在Service._meta.virtual_fields 中可用。
    • virtual_fields 也已经过时了,至少对于 django 2.0
    • 2021 年更新:virtual_fields 也已过时。现在是_meta.private_fields 获取所有GenericRelations()
    【解决方案2】:

    2021 年更新:

    列出所有GenericRelations() 字段:

    print(Service._meta.private_fields)
    

    输出:

    [<django.contrib.contenttypes.fields.GenericRelation: statuses>]
    

    不过,如果您有更多具有GenericRelations() 关系的字段,它们将显示在输出列表中。

    查看文档:

    https://docs.djangoproject.com/en/3.2/releases/1.10/#id3

    或者您可以返回所有具有GenericRelation() 字段类型的字段。

    例如:

    # models.py
    class MyModel(models.Model):
        . . .
        my_model_field = GenericRelation(OtherPolyModel)
    
    
    def get_generic_relation_fields(self):
       """
       This function returns all the GenericRelation 
       fields needed to return the values that are 
       related to a polymorphic model.
       """
       fields = [f.attname for f in self.Meta.model._meta.get_fields()]
       file_fields = []
       for field in fields:
           get_type = self.Meta.model._meta.get_field(field)
           field_type = get_type.__class__.__name__
                
           if field_type == "GenericRelation":
               file_fields.append(field)
    
           return file_fields
    

    输出:

    ['my_model_field']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-22
      • 2011-07-20
      • 1970-01-01
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多