1.你并没有真正得到任何python继承,也就是说你不能在你的类Restaurant中继承/覆盖模型类Place的方法或属性:
例如:
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
这意味着要获得您不能做a_restaurant.name的餐厅的name,您需要点击链接:a_restaurant.place.name
另请注意,在使用相关的Restaurant 查询Place 对象时。
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,您可以使用Restaurant 数据查询Place 对象:
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]
希望这些有所帮助。它长得有点太长了:/