我想这样做:
class Place(models.Model):
name = models.CharField(max_length=20)
rating = models.DecimalField()
class LongNamedRestaurant(Place): # Subclassing `Place`.
name = models.CharField(max_length=255) # Notice, I'm overriding `Place.name` to give it a longer length.
food_type = models.CharField(max_length=25)
这是我想使用的版本(尽管我愿意接受任何建议): http://docs.djangoproject.com/en/dev/topics/db/models/#id7
Django支持这个吗?如果没有,是否有办法达到类似的效果?
除非是抽象的,否则这是不可能的,这就是为什么:
LongNamedRestaurant
也是一个Place
,不仅作为一个类而且在数据库中。place表包含每个纯Place
和每个LongNamedRestaurant
的条目。LongNamedRestaurant
只需创建一个带有food_type
和对place表的引用的额外表。如果你做了
Place.objects.all()
,你也得到了每个LongNamedRestaurant
的地方,它将是Place
(没有food_type
)的一个实例。因此Place.name
和LongNamedRestaurant.name
共享同一数据库列,因此必须属于同一类型。我认为这对普通模特来说是有意义的:每家餐馆都是一个地方,至少应该有那个地方所有的东西。也许这种一致性也是为什么1.10之前的抽象模型不可能实现的原因,尽管它不会带来数据库问题。正如@lampsave所说,这是在1.10中实现的。我个人建议注意:如果Sub.x重写Super.x,请确保Sub.x是Super.x的子类,否则不能使用Sub代替Super。
解决方法:您可以创建一个自定义用户模型(
AUTH_USER_MODEL
),如果只需要更改email字段,则该模型会涉及相当多的代码重复。或者你可以留下电子邮件,并确保它是所有形式的要求。如果其他应用程序使用它,这不能保证数据库的完整性,也不能以其他方式工作(如果您想使用户名成为不需要的)。不,it is not:
更新的答案:正如人们在评论中指出的,最初的答案没有正确回答问题。实际上,只有
LongNamedRestaurant
模型是在数据库中创建的,Place
不是。解决方案是创建一个抽象模型来表示一个“地方”,例如
AbstractPlace
,并从中继承:也请阅读@Markanswer,他给出了一个很好的解释,为什么不能更改从非抽象类继承的属性。
(注意,这是唯一可能的,因为Django 1.10:在Django 1.10之前,无法修改从抽象类继承的属性。)
相关问题 更多 >
编程相关推荐