wha*_*atf 8 django django-models
我有这个用例场景:有些地方是游乐场,餐馆,剧院,酒吧.同样place可以有游乐场,餐馆,剧院等.有几种方法可以实现它:
使用外键
class Place(models.Model):
name = models.CharField(max_length=50)
class PlayGrounds(models.Model)
field1 = models.CharField(max_length=50)
place = models.ForeignKey(Place)
Run Code Online (Sandbox Code Playgroud)多元遗传
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(Place):
serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField()
Run Code Online (Sandbox Code Playgroud)使用抽象类
class Place(models.Model):
name = models.CharField(max_length=50)
class PlayGrounds(Place)
field1 = models.CharField(max_length=50)
place = models.ForeignKey(Place)
class Meta:
abstract = True
Run Code Online (Sandbox Code Playgroud)使用代理模型
class Place(models.Model):
name = models.CharField(max_length=50)
class PlayGrounds(Place)
field1 = models.CharField(max_length=50)
place = models.ForeignKey(Place)
class Meta:
proxy = True
Run Code Online (Sandbox Code Playgroud)使用每种方法的利弊是什么?
Chr*_*att 15
第一个是基本模型继承,因为这是Django的实现MTI的使用(除非它是一个OneToOneField替代的ForeignKey,但是这仅仅是ForeignKey这是唯一的).
任何时候你都有一个is-a关系(即,一个餐馆就是一个地方),你正在处理继承,所以使用Django的模型继承方法之一就是要走的路.然而,每个都有其优点和缺点:
抽象模型
当您只想卸载重复的字段和/或方法时,抽象模型很有用.他们最好用作mixins,而不仅仅是真正的"父母".例如,所有这些模型都有一个地址,因此创建一个抽象Address模型并从中继承每个模型可能是一个有用的东西.但是,a 本身Restaurant并不是一个Address,所以这不是一个真正的亲子关系.
MTI(多表继承)
这是与您上面的第一选择类似的那个.当您需要与父类和子类进行交互并且子项具有自己的唯一字段(字段,而不是方法)时,这非常有用.所以Restaurant可能有一个cuisine领域,但Place不需要.但是,它们都有一个地址,所以Restaurant继承和构建Place.
代理模型
代理模型就像别名.他们不能拥有自己的领域,只能获得父级的领域.但是,它们可以有自己的方法,因此当您需要区分相同的东西时,这些方法很有用.例如,我可能会创建类似StaffUser和NormalUser来自的代理模型User.仍然只有一个用户表,但我现在可以为每个用户表添加唯一的方法,创建两个不同的管理员视图等.
对于您的方案,代理模型没有多大意义.孩子天生就比母公司更复杂,这是没有意义的存储所有喜欢的领域cuisine为Restaurant上Place.
你可以使用抽象Place模型,但是你失去了实际工作的能力Place.当你想要一个外键到一个通用的"地方"时,你将不得不使用通用的外键,而是能够从不同的地方类型中进行选择,如果没有必要,会增加很多开销.
你最好的选择是使用正常继承:MTI.然后,您可以创建一个外键Place并添加任何子项Place.