【问题标题】:Is there a way to get type of related field from a model queryset in Django?有没有办法从 Django 中的模型查询集中获取相关字段的类型?
【发布时间】:2013-03-20 04:15:46
【问题描述】:

我可以从模型查询集中获取相关字段的类型吗?

让我们考虑示例模型:

class Semester(models.Model):
    active = models.BooleanField(default=False, verbose_name="Active")

class Subject(models.Model):
    name = models.CharField(max_length=100, verbose_name="Name")
    semester = models.ForeignKey(Semester, verbose_name="Semester")

如果我在变量和查询集中有一些字段名,我可以这样做:

querySet = Subject.objects.all()

some_field_name = 'name'
field_type = querySet.model._meta.get_field(some_field_name).get_internal_type()

有没有办法获取相关字段类型,例如:

querySet = Subject.objects.all()

some_field_name = 'semester__active'
field_type = ?

【问题讨论】:

  • for subject in querySet: print type(subject.semester.active)?
  • 感谢您的建议,但是 type() 返回对象的类型,不幸的是我需要字段类型

标签: django django-queryset


【解决方案1】:

尝试使用get_field_by_name

field_type = querySet.model._meta.get_field_by_name(some_field_name).get_internal_type()

来自Django's source code

def get_field_by_name(self, name):
    """
    Returns the (field_object, model, direct, m2m), where field_object is
    the Field instance for the given name, model is the model containing
    this field (None for local fields), direct is True if the field exists
    on this model, and m2m is True for many-to-many relations. When
    'direct' is False, 'field_object' is the corresponding RelatedObject
    for this field (since the field doesn't have an instance associated
    with it).

    Uses a cache internally, so after the first access, this is very fast.
    """

也试试:

field = querySet.model._meta.get_field_by_name("semester")
field_type = field[0].rel.to._meta.get_field_by_name("active").get_internal_type()

【讨论】:

  • 感谢您的回答,但不幸的是 .get_field_by_name("active") 返回 FieldDoesNotExist 错误。你的另一个建议 querySet.model._meta.get_field_by_name("semester").rel.get_field_by_name("active").get_internal_type() return AttributeError 'tuple' object has no attribute 'rel'
  • 请用field_type = field[0].rel.get_field_by_name("active").get_internal_type()重试第二个建议
  • 不幸的是,您编辑的建议返回 AttributeError: 'ManyToOneRel' object has no attribute 'get_field_by_name'
  • 嗯好的。 field[0].rel.to.get_field_by_name("active").get_internal_type() 呢?
  • AttributeError:类型对象“学期”没有属性“get_field_by_name”。您应该添加 _meta,正如您在我的回答中看到的那样:field[0].rel.to._meta.get_field_by_name('active').get_internal_type()。感谢您的帮助
【解决方案2】:

感谢您的帮助!

我在this answer 的帮助下找到了解决方案:

main, related = some_field_name.split("__")
field_type = querySet.model._meta.get_field(main).rel.to._meta.get_field(related).get_internal_type()

【讨论】:

  • 这行得通但是很丑,因为它重新实现了 Django 的一部分:-s
猜你喜欢
  • 2020-03-05
  • 2011-04-11
  • 2020-08-14
  • 2013-02-17
  • 2018-12-17
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 2020-07-31
相关资源
最近更新 更多