在Django中表示两个非常相似但不同的对象的更好方法是什么?

时间:2016-07-24 18:36:07

标签: django database data-modeling

所以我正在尝试为“房屋”和“房屋小组”建立一个好方法。

房屋和住宅小组非常相似,因为它们都带有描述并且有相关的定价信息。

但是,“预订”只能分配给Houses而不是HouseGroups。

目前,我的模型看起来像这样:

class Houselike(models.Model):
    max_guests = models.IntegerField()
    name = models.CharField(max_length=20)
    description = models.TextField(blank=True)

class House(Houselike):
    pass

class HouseGroup(Houselike):
    houses = models.ManyToManyField(House)

从语义上讲,这实际上非常接近我想要的。但是,在数据库中,这导致有两个表只有一个字段“houselike_ptr_id”引用“Houselike”基础对象。

检查Houselike对象是House还是Housegroup,因此需要查看两个不同的表格。

更有效的替代方案是:

class Houselike(models.Model):
    max_guests = models.IntegerField()
    name = models.CharField(max_length=20)
    description = models.TextField(blank=True)
    is_group = models.BooleanField()
    houses = models.ManyToManyField(House)

这导致“houselike”表中只有1个额外字段,而另一个包含相关房屋的表只有在我们实际查找它们时才会被击中。从存储的角度来看,这是恕我直言的最佳解决方案。

然而,从语义的角度来看,这并不是很好:House和Housegroups是相似的,但不同的对象。

此外,这允许像包含其他房屋组的房屋组,包含房屋的非组,以及我必须手动检查的东西。

我也非常希望能够明确使用HouseHouseGroup个对象。用同一个班级代表他们只是感觉不对。

有更好的方法吗?

编辑:

我忘了提及定价信息(以及其他实体)可以与众议院或众议院小组相关联,并且(大致)实施如下:

class PricePeriod(models.Model):
    house = models.ForeignKey(Houselike, on_delete=models.CASCADE)
    arrival_date = models.DateField()
    # Date of last departure date
    departure_date = models.DateField()
    price = models.DecimalField(max_digits = 10, decimal_places=2)

这就是为什么我不简单地将Houselike作为一个抽象模型,因为这些其他对象与它有关。

1 个答案:

答案 0 :(得分:0)

事实证明,这就是所谓的“单表继承”,这在我的案例中是完美的。

而且,这是互联网,有一个应用程序:https://github.com/craigds/django-typed-models

from typedmodels.models import TypedModel

# Create your models here.

class Houselike(TypedModel):
    max_guests = models.IntegerField()
name = models.CharField(max_length=20)
description = models.TextField(blank=True)

class House(Houselike):
    pass

class HouseGroup(Houselike):
    houses = models.ManyToManyField(House)

这导致了我的要求:数据库中的单个表,以及Python / Django中显式的,语义正确的模型。

现在我只需要修复我糟糕的命名......