在Django中,有没有一种方法可以从模型查询集中获取相关字段的类型?

4

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

让我们考虑一个示例模型:

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 = ?

对于查询集中的每个主题:打印类型(subject.semester.active)是什么? - Bibhas Debnath
谢谢您的建议,但是type()返回一个对象的类型,不幸的是我需要字段类型。 - Lukasz Koziara
2个回答

2
尝试使用get_field_by_name
field_type = querySet.model._meta.get_field_by_name(some_field_name).get_internal_type()

来自Django源代码

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()返回AttributeError 'tuple' object has no attribute 'rel'。 - Lukasz Koziara
请尝试使用field_type = field[0].rel.get_field_by_name("active").get_internal_type()的第二个建议再次尝试。 - Dan Aronne
不幸的是,您编辑的建议返回AttributeError: 'ManyToOneRel'对象没有'get_field_by_name'属性。 - Lukasz Koziara
嗯,好的。那么 field[0].rel.to.get_field_by_name("active").get_internal_type() 呢? - Dan Aronne
属性错误:类型对象“Semester”没有属性“get_field_by_name”。您应该添加_meta,就像我在我的答案中所示:field [0] .rel.to._meta.get_field_by_name('active').get_internal_type()。感谢您的帮助。 - Lukasz Koziara
噢,好的,我明白了。很高兴你找到了答案。祝你好运! - Dan Aronne

1

谢谢您的帮助!

这个答案的帮助下,我找到了解决方案:

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

这个可以工作,但是它重新实现了 Django 的一部分,看起来有点丑。 - Ciro Santilli OurBigBook.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接