【问题标题】:Django model inheritance: Create a subclass using existing super classDjango模型继承:使用现有超类创建子类
【发布时间】:2012-04-06 23:51:16
【问题描述】:

我正在使用multi-table-inheritance,并且想知道如何从超类的实例创建继承类型。

使用文档中给出的示例:

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

【问题讨论】:

标签: django inheritance model


【解决方案1】:

虽然没有记录,但这似乎可以解决问题:

restaurant(place_ptr=place).save_base(raw=True)

这在不使用任何技巧的情况下解决了问题,并且在处理方面也是最短的解决方案,使用 Django API。

在搜索此解决方案时,我还找到了一个稍长的解决方案,但使用了文档化的 API。与Mariusz answer基本相同,详情见this answer

from django.forms.models import model_to_dict

restaurant(place_ptr=place, **model_to_dict(place)).save()

但是,由于 model_to_dict 返回的字段集有限,第二个风险更大(再次查看解释所呈现的各种方法之间差异的答案)。自然,它还会生成更多的 DB 调用,因为它写入两个表。

【讨论】:

    【解决方案2】:
    place = Place.objects.get(id=1)
    
    # Create a restaurant using existing Place
    place.__class__ = Restaurant
    place.save()
    restaurant = place
    

    【讨论】:

      【解决方案3】:

      多表继承只是Place 和Restaurant 之间的OneToOneField 关系。

      place = Place.objects.get(id=1)               
      
      # Create a restaurant using existing Place   
      restaurant = Resturant(place_ptr=place)
      restaurant.save()
      

      【讨论】:

      • 这将导致 restaurant.name 被清空。因为 restaurant.save() 会用 name='' 更新 Place(因为 restaurant = Resturant())...一定有更好的方法...
      • 你应该添加 restaurant.__dict__.update(place.__dict__),见Daniel Roseman's answer
      • 好的,结合 secator 的答案和 jpic 的添加就可以了...
      猜你喜欢
      • 2012-05-04
      • 2015-03-05
      • 1970-01-01
      • 2020-03-02
      • 2014-02-12
      • 1970-01-01
      • 2014-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多