1.你并没有真正得到任何python继承,也就是说你不能从Place
你的类中的模型类继承/覆盖方法或属性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
因为它们是继承的。
由于使用这些实现 aRestaurant
也是a 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]
希望这些有所帮助。它长得有点太长了:/