如何检查Django中多对多字段的类型?
在Django中,怎么检查一个多对多字段的类型呢?
我想这样做:
import django
field.__class__ == django.db.models.fields.related.ManyRelatedManager
这样做不行,因为找不到名为 ManyRelatedManager
的类。不过如果我用 field.__class__
,输出的结果是 django.db.models.fields.related.ManyRelatedManager
。
为什么它提到一个看起来不存在的类,我该怎么才能让它正常工作呢?
非常感谢你的帮助。
4 个回答
2
(使用 Django 1.11)
这个问题变得有些混乱,因为报告的行为与现代相关字段的行为不一致。这里有个例子,其中 JobTemplate
是模型类,而 credentials
是一个多对多的相关字段:
>>> JobTemplate._meta.get_field('credentials').__class__
django.db.models.fields.related.ManyToManyField
如果我们检查一个对象的 _meta
,会有什么不同吗?
>>> JobTemplate.objects.first()._meta.get_field('credentials').__class__
django.db.models.fields.related.ManyToManyField
不会。
接下来,我想插入一个我认为最有可能的场景,可能会有人来这里。你有这个:
>>> JobTemplate.objects.first().credentials
<django.db.models.fields.related_descriptors.ManyRelatedManager at 0x6f9b390>
注意,这就是提问者所拥有的。
我会假设相关模型是 Credential
。我可以检查这是否是一个相关的凭证管理器!
>>> isinstance(JobTemplate.objects.first().credentials, Credential.objects.__class__)
True
多对多字段可能很难处理,因为这个属性会自我销毁,并用管理器的子类替代。你也可以通过 get_field('credentials')
获取的字段来交叉验证这些信息,以确保准确。上面的 isinstance
检查也可能错误地识别出你在模型上设置的其他管理器。不过,这仍然是一个有价值的测试,可以看看你拥有的属性是否“像”那个特定相关模型的多对多字段应该那样工作。
20
你可以把它当作一个字符串来检查。
field.__class__.__name__ == 'ManyRelatedManager'
7
如果你已经有了字段实例,你可以直接这样做:
if isinstance(field, ManyToManyField):
pass // stuff
如果你只有相关的管理器实例,你可以反向查找字段实例:
>>> print fm
<class 'django.db.models.fields.related.ManyRelatedManager'>
>>> print fm.instance._meta.get_field_by_name('fieldnamehere')
(<django.db.models.fields.related.ForeignKey: fieldnamehere>, None, True, False)
这个方法只在Django 1.5上测试过。