多表继承模型和相同的两个模型之间的简单一对一关系有什么区别? [英] What is the difference between a Multi-table inherited model and a simple One-to-one relationship between the same two models?

查看:19
本文介绍了多表继承模型和相同的两个模型之间的简单一对一关系有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些实现之间有什么区别?Django 有什么不同(除了继承 Meta orderingget_latest_by 属性)?

What is the differences between these implementations? What does Django differently (beside inheriting Meta ordering and get_latest_by attribute) ?

# 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 在你的类 Restaurant 中:

1. You don't really get any python inheritance, that is you can't inherit/override methods or attributes from the model class Place in your 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

This means that to obtain the name of a restaurant you can't do a_restaurant.name, you would need to follow the link: a_restaurant.place.name

另请注意,在查询具有相关 RestaurantPlace 对象时.

Also note that when querying a Place object with the related 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 继承.


2 and 3. are almost the same. You do get real python inheritance with these.

a_restaurant = Restaurant()
a_restaurant.get_x() # would actually work and print 'x'

您的模型类 Restaurant 继承了 Place 的所有内容:模型字段、普通实例/类属性、管理器、方法……您还可以覆盖其中的几乎任何内容:您不能覆盖字段属性,这是不受支持的.

Your model class Restaurant inherits everything from Place: model fields, normal instance/class attributes, managers, methods... and you can also override almost anything of these: You can't override field attributes, that's not supported.

所以现在您可以直接从父模型中获取字段的值:a_restaurant.name 因为它们是继承的.

So now you can get the values of the fields from the parent model directly:a_restaurant.name because they are inherited.

由于有了这些实现,Restaurant is 也是 Place,您可以使用 Place 查询Place 对象代码>餐厅数据:

Since with these implementation a Restaurant is a also Place you can query for a Place object with Restaurant data:

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:

Works exactly the same but to obtain the parent place of a Restaurant the attribute name is where:

the_place = a_restaurant.where

使用 2 本来是:

the_place = a_restaurant.place_ptr

这意味着 place = models.OneToOneField(Place, parent_link=True) 只会更改父模型实例的链接名称.默认名称为 '{lowercase_model_name}_ptr'.

These means that place = models.OneToOneField(Place, parent_link=True) will only change the name of the link to the parent model instance. The default name is '{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]

<小时>

希望这些有帮助.它长得太长了:/


Hope these helps. It grow a bit too long :/

这篇关于多表继承模型和相同的两个模型之间的简单一对一关系有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆