我正在使用多表继承,并且想知道如何从超类的实例创建继承的类型。
使用文档中给出的示例:
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
class Restaurant(Place):
serves_hot_dogs = models.BooleanField()
serves_pizza = models.BooleanField()
现在,当您创建Restaurant
时,您会自动生成Place
,这很好,以及我期望和想要的行为。
但是,如果我制作了一个Place
,然后决定要转换为特定类型(如Restaurant
),该怎么办。如何使用现有的Place
创建Restaurant
?
多表继承只是Place和Restaurant之间的OneToOneField
关系。
place = Place.objects.get(id=1)
# Create a restaurant using existing Place
restaurant = Resturant(place_ptr=place)
restaurant.save()
place = Place.objects.get(id=1)
# Create a restaurant using existing Place
place.__class__ = Restaurant
place.save()
restaurant = place
虽然没有记录,但这似乎起到了作用:
restaurant(place_ptr=place).save_base(raw=True)
这在不使用任何技巧的情况下解决了这个问题,也是使用Django API进行处理的最短解决方案。
在搜索这个解决方案时,我还发现了一个稍长的解决方案,但使用了文档化的API。它基本上与Mariusz的答案相同,也可以参见此答案了解更多详细信息:
from django.forms.models import model_to_dict
restaurant(place_ptr=place, **model_to_dict(place)).save()
然而,由于model_to_dict返回的字段集有限,第二种方法的风险更大(请再次参阅解释各种方法之间差异的答案)。自然地,它还会生成更多的DB调用,因为它同时写入两个表。