django - 多表继承模型和相同的两个模型之间的简单一对一关系有什么区别?

标签 django inheritance orm model

这些实现之间有什么区别? Django 有什么不同(除了继承 Meta orderingget_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/

相关文章:

sql - 具有继承性的 PostgreSQL 外键

c# - 一个 DbContext 和多个数据库,EF 代码优先

java - Hibernate/JPA OneToMany 是否应该在两侧进行更新?

python - Django ManyToManyField 在管理中保存时出错?

python - django-import-export 无法正常工作

django - 是否可以仅使用 Nginx 和 Daphne 来为 Django Channels 应用程序提供服务?

java - 如何跳过扩展抽象类的类中的一个方法?

c++ - 我误用了继承权吗?

java - Hibernate native 查询可选参数抛出 'operator does not exist: bigint = bytea'

Django 本地化 : labels don't get updated