我目前正在研究Django中的一个模型,该模型涉及一个模型,该模型可以具有各种不同的特征,具体取决于它是什么类型的对象。所以,假设我们有一个名为Mammal的模型,它可以是大象或海豚(分别具有自己的特征“tusk_length”和“flipper_length”)。
基本的OOP原则呼喊“多态”,我倾向于同意。但是,由于我是Django的新手,我首先要知道它是否是Django中最好的方法。我听说过很多例子和一些人对奇异巨型模特的偏好
我已经尝试过使用GenericForeignKeys,如下所述:How can I restrict Django's GenericForeignKey to a list of models?。虽然这个解决方案运行得很漂亮,但我不喜欢无法过滤,而且这种关系只是一种方式。也就是说,虽然你可以从哺乳动物物体中获得海豚,但是你无法从海豚身上获得哺乳动物物体。
所以,这是我的两个选择:
选择A:
from django.db import models
class Mammal(models.Model):
hair_length = models.IntegerField()
tusk_length = models.IntegerField()
flipper_length = models.IntegerField()
animal_type = models.CharField(max_length = 15, choices = ["Elephant", "Dolphin"]
选择B:
from django.db import models
class Mammal(models.Model):
hair_length = models.IntegerField()
class Elephant(Mammal):
tusk_length = models.IntegerField()
class Dolphin(Mammal):
flipper_length = models.IntegerField()
根据我的理解,选择B在查询和列出所有大象或海豚时具有更好的代码优势。但是,我注意到从哺乳动物列表中获取所有大象并不是那么简单(有没有查询?)而没有在类中放入animal_type,默认依赖于类。
这导致了我看到的多态性的另一个问题,在上面的例子或我的应用程序中都没有出现,但值得一提的是,如果不完全删除Dolphin,很难将Dolphin对象编辑成Elephant
总的来说,是否有任何普遍的偏好,或者我不应该使用多态的任何重大原因?
答案 0 :(得分:6)
我的建议,一般是数据库设计,是为了避免继承。它使访问和更新变得复杂。
在Django中,尝试使用基本模型的抽象类。这意味着不会为它创建db表。其字段/列将在其子模型中自动创建。好处是:Django / Python代码中的代码重用以及数据库中的简单平面设计。惩罚是:管理/查询混合的子模型集合需要做更多的工作。
请在此处查看示例:Django Patterns: Model Inheritance
或者,您可以将“哺乳动物”的概念更改为“MammalTraits”。并在每个特定的哺乳动物类中包含一个MammalTraits对象。在代码中,即组合(has-a)。在db中,将表示为外键。
答案 1 :(得分:1)
我们最终选择了一个包含大量通常为空的列的大表。我们的理由是(在这种情况下)我们的哺乳动物表是我们要查询的全部,除了手动检查他们是否有“海豚”或“大象”之外,没有(直观的)方法可以过滤掉某些类型的哺乳动物“对象,如果他们没有,则会抛出错误。甚至寻找从绝对是大象的查询返回的对象的类型仍然返回“哺乳动物”。很难将任何Pythonic变通方法扩展到编写纯SQL,我们的数据人员经常这样做。