Django 多表继承模型与同两个模型之间的简单一对一关系有什么区别?
这些实现之间的区别是什么?Django有什么不同之处(除了继承MetaDjango 多表继承模型与同两个模型之间的简单一对一关系有什么区别?,django,inheritance,orm,model,Django,Inheritance,Orm,Model,这些实现之间的区别是什么?Django有什么不同之处(除了继承Metaordering和get\u latest\u by属性) 1. 2. 3. 1-要创建餐厅,您需要创建地点,在创建餐厅之后,在链接它们之后, 2-然后创建餐厅,创建并自动链接新场所, 3-您已将父链接重命名为place 使用带有内容类型的模型继承,您可以列出在Place.objects.all()上迭代的所有咖啡馆、餐馆、酒吧等。1。您实际上不会得到任何python继承,也就是说,您不能继承/重写类中模型类Place的方法或
ordering
和get\u latest\u by
属性)
1.
2.
3.
1-要创建餐厅,您需要创建地点,在创建餐厅之后,在链接它们之后, 2-然后创建餐厅,创建并自动链接新场所, 3-您已将父链接重命名为place
使用带有内容类型的模型继承,您可以列出在Place.objects.all()上迭代的所有咖啡馆、餐馆、酒吧等。1。您实际上不会得到任何python继承,也就是说,您不能继承/重写类中模型类
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
,您需要遵循以下链接:a_restaurant.place.name
还请注意,当查询带有相关餐厅的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
,因为它们是继承的
由于使用这些实现,餐厅
也是一个场所
,因此您可以使用餐厅
数据查询场所
对象:
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()
工作原理完全相同,但要获取餐厅的父位置
属性名称为其中
:
the_place = a_restaurant.where
如果2,则:
the_place = a_restaurant.place_ptr
这意味着place=models.OneToOneField(place,parent\u link=True)
将只更改链接到父模型实例的名称。默认名称是{lowercase\u model\u name}\u 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]
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]
使用2-3:
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]
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]
希望这些有帮助。它变得有点太长了://我个人的意见:2º选项似乎是这个示例的最佳实现,因为
餐厅
确实是一个地方
。非常好的解释,我没想到会这么长:)谢谢!注意:在Django 1.5中,子模型的OneToOneField的默认名称是objectname.parentobject\u ptr
(不是objectname.parentobject)。因此,您可以使用a_餐厅查询地点。Place_ptr
in#2。但是另一种方式(从地点查询)是:a_place.restaurant
@Adrian你必须写:a_restaurant.save()place.objects.get(restaurant_upk=a_restaurant.pk)如果餐馆来自/包含地点,而不是反过来,我不明白我们如何写restaurant_upk。Thanks@dowjones123Django可以向后跟踪(和查询)关系。看一看,特别是我想用额外的字段扩展内置站点框架站点模型,并尝试决定哪种方法最好。
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]