Django:从一个超类继承继承访问多个子类的某些属性

时间:2018-12-12 01:22:22

标签: django inheritance django-models subclass multiple-choice

我的目标是访问子类的属性,而无需事先知道选择了两个子类中的哪个(多选类)

理想情况下,SuperClass中有一个属性会根据选择的子类而变化。

原因是我直接从子类创建了Forms,并使用SuperClass作为访问值的入口点。

我知道我可以对hasattr(horse)使用true或false,但是理想情况下,我想问是否有一些更整洁的解决方案,例如SubClass可以向SuperClass发出信号,说明使用了哪个SubClass。

例如我列表中的产品8

subclass = getattr(Product(8), 'subclass', 0)
print(subclass)
>> Horse

place = Product.location
Print(place)
>> Stable

整个“问题”源于我通过SubClass Forms创建产品的事实,与此同时,从产品开始,随后的大部分逻辑自上而下

class Product(models.Model):
  product_name = models.Charfield(max_length=20)

class Car(Product):
  engine = models.Charfield(max_length=20)
  location = models.Charfield(default="Garage", max_length=20, editable=False)
  product = models.OneToOneField(Product, parent_link=True, on_delete=models.CASCADE)

class Horse(Product):
  saddle_model = models.Charfield(max_length=20)
  location = models.Charfield(default="Stable", max_length=20, editable=False)
  product = models.OneToOneField(Product, parent_link=True, on_delete=models.CASCADE)

1 个答案:

答案 0 :(得分:1)

如果要从Product模型访问其他模型属性,则可以在Product上实现property method,以检查其与相关模型之间的反向关系,然后返回适当的位置(https://docs.djangoproject.com/en/2.1/topics/db/examples/one_to_one/ )。

class Product(models.Model):
    product_name = models.CharField(max_length=20)

    @property
    def location(self):
        """Return the location of the related subclass"""
        if self.car:
            return self.car.location
        elif self.horse:
            return self.horse.location
        else:
            return None

    @property
    def product_subclass(self):
        """Return the location of the related subclass"""
        if self.car:
            return self.car
        elif self.horse:
            return self.horse
        else:
            return None

这应该允许您像这样使用它:

car_product = Product.objects.create(product_name="Car Product")
car = Car.objects.create(engine="engine", location="123 Fake Street", product=car_product)
print(car_product.location)  # Prints "123 Fake Street"

horse_product = Product.objects.create(product_name="Horse Product")
horse = Horse.objects.create(saddle_model="Buckingham", location="1982 Old Street", product=horse_product)
print(horse_product.location)  # Prints "1982 Old Street"

如果您想做类似的事情来返回子类:

print(car_product.product_subclass)  # Prints <Car object>
print(horse_product.product_subclass)  # Prints <Horse object>

这些属性方法需要数据库查询来检查Car和Horse表,因为该关系作为product_id列存储在这些表中。因此,要确定product.car是否有效,ORM会执行类似于Car.objects.get(product_id=product.pk)

的查询
相关问题