这些实现之间有什么区别? Django 有什么不同(除了继承 Meta ordering
和 get_latest_by
属性)?
1.
# models.py
from django.db import models
class Place(models.Model):
name = models.CharField(max_length=50)
class Restaurant(models.Model):
place = models.OneToOneField(Place)
serves_pizza = models.BooleanField()
2.
class Place(models.Model):
name = models.CharField(max_length=50)
class Restaurant(Place):
serves_pizza = models.BooleanField()
3.
class Place(models.Model):
name = models.CharField(max_length=50)
class Restaurant(Place):
place = models.OneToOneField(Place, parent_link=True)
serves_pizza = models.BooleanField()
最佳答案
1. 你并没有真正获得任何 python 继承,也就是说你不能从模型类中继承/覆盖方法或属性 Place
在你的类(class) Restaurant
:
例如:
class Place(models.Model):
name = models.CharField(max_length=50)
def get_x(self):
return 'x'
class Restaurant(models.Model):
place = models.OneToOneField(Place)
serves_pizza = models.BooleanField()
a_restaurant = Restaurant()
a_restaurant.get_x() # -> wouldn't work
这意味着要获得
name
不能做的餐厅 a_restaurant.name
,您需要点击以下链接:a_restaurant.place.name
另请注意,在查询
Place
时对象与相关 Restaurant
.a_restaurant.save()
Place.objects.get(pk=a_restaurant.pk) # won't work
你必须写:
a_restaurant.save()
Place.objects.get(restaurant__pk=a_restaurant.pk)
2 和 3 .几乎相同。你确实得到了真正的 Python 继承。
a_restaurant = Restaurant()
a_restaurant.get_x() # would actually work and print 'x'
您的模型类
Restaurant
继承了 Place
的所有内容: 模型字段、普通实例/类属性、管理器、方法......你还可以覆盖几乎所有这些:您不能覆盖字段属性,这是不受支持的。
所以现在你可以直接从父模型中获取字段的值:
a_restaurant.name
因为它们是遗传的。因为有了这些实现
Restaurant
是 也Place
您可以查询 Place
对象 Restaurant
数据:a_restaurant.save()
the_place = Place.objects.get(pk=a_restaurant.pk)
# ^ this works now and returns the equivalent `Place` instance.
the_same_restaurant = the_place.restaurant
差异如果为该字段指定不同的名称,则更容易查看 2 和 3 之间的名称:
class Place(models.Model):
name = models.CharField(max_length=50)
class Restaurant(Place):
where = models.OneToOneField(Place, parent_link=True)
serves_pizza = models.BooleanField()
工作原理完全相同,但获取
Restaurant
的父位置属性名称是 where
:the_place = a_restaurant.where
与 2 本来可以:
the_place = a_restaurant.place_ptr
这意味着
place = models.OneToOneField(Place, parent_link=True)
只会更改指向父模型实例的链接的名称。默认名称是 '{lowercase_model_name}_ptr'
.最后一个例子:
与 1 :
place1 = Place.objects.create(name='place_1')
place2 = Place.objects.create(name='place_2')
restaurant1 = Restaurant.objects.create(place=place1, serves_pizza=True)
print Place.objects.all() # prints [place1, place2]
print Restaurant.objects.all() # prints [restaurant1]
与 2-3 :
place1 = Place.objects.create(name='place_1')
place2 = Place.objects.create(name='place_2')
restaurant1 = Restaurant.objects.create(name='place_3', serves_pizza=True)
print Place.objects.all() # prints [place1, place2, place3]
print Restaurant.objects.all() # prints [restaurant1]
希望这些有帮助。它长得太长了:/
关于django - 多表继承模型和相同的两个模型之间的简单一对一关系有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18292604/