在Django中获取变量OneToOneField

时间:2019-12-30 19:55:38

标签: python django django-models

让我们说我有一个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)?

3 个答案:

答案 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

可能有一些缺点(可能是运行时不好),但目前已达到目的。 对此有改进的想法表示赞赏

相关问题