让我们说我有一个Form
模型:
class Form(models.Model):
name = models.TextField()
date = models.DateField()
和各种“子”模型
class FormA(models.Model):
form = models.OneToOneField(Form, on_delete=models.CASCADE)
property_a = models.TextField()
class FormB(models.Model):
form = models.OneToOneField(Form, on_delete=models.CASCADE)
property_b = models.IntegerField()
class FormC(models.Model):
form = models.OneToOneField(Form, on_delete=models.CASCADE)
property_c = models.BooleanField()
Form
可以是3种形式(FormA,FormB,FormC)中的一种,并且只能是其中一种。给定一个Form
的查询集,我有什么方法可以恢复它们是什么类型的表单(A,B或C)?
答案 0 :(得分:1)
您可以按名称或实例进行检查。
a = FormA()
print(a.__class__)
print(a.__class__.__name__)
print(isinstance(a, Forma))
输出:
<class __main__.FormA at 0xsomeaddress>
'FormA'
True
-------------------编辑----------------- 好的,根据您的评论,您只想知道将哪个实例分配给您的主表单。
因此您可以执行以下操作:
if hasattr(form, 'forma'):
# do something
elif hasattr(form, 'formb'):
# do something else
elif hasattr(form, 'formb'):
# do something else
答案 1 :(得分:1)
我需要更好地了解您的实际用例,以了解这是否对您来说是一个不错的选择,但是在这些情况下,我首先建议使用model inheritance而不是一对一领域。您那里的代码基本上可以完成multi-table inheritance已经完成的工作。
首先快速真正地阅读继承文档,并确保与django提供的其他选项相比,多表继承对您有意义。如果您确实希望继续进行多表继承,建议您看看InheritanceManager from django-module-utils。
在这一点上(如果使用InheritanceManager
),您将可以使用isinstance
。
for form in Form.objects.select_subclasses():
if isinstance(form, FormA):
..... do stuff ......
这听起来可能要付出很多额外的努力,但IMO会减少活动部件(和自定义代码),并使事情更容易处理,同时仍能处理所需的功能。
答案 2 :(得分:0)
经过一番调查,我想到了这个
for form in forms:
#reduces fields to those of OneToOne types
one_to_ones = [field for field in form._meta.get_fields() if field.one_to_one]
for o in one_to_ones:
if hasattr(form,o.name):
#do something
可能有一些缺点(可能是运行时不好),但目前已达到目的。 对此有改进的想法表示赞赏