2010-07-04 152 views
3

我有一些代码遵循文档页面上给出的多表继承的示例:http://docs.djangoproject.com/en/dev/topics/db/models/#multi-table-inheritance。我想要做的是在一个地方周围创建一家餐厅。Django多表继承和模型创建

我已经创建了一个地方,我想打一个餐厅吧,像这样:

>>> p = Place.objects.get(id=12) 
# If p is a Restaurant object, this will give the child class: 
>>> p.restaurant 
<Restaurant: ...> 
>>> r = Restaurant(p) 

但我得到这个错误:

TypeError: int() argument must be a string or a number, not 'Place' 

我要添加更多信息给我的模型,所以我不想进去并手动设置所有的字段是平等的。无论如何要做到这一点?

回答

1

我想你应该添加一个外键到餐厅,像这样​​:

class Place(models.Model): 
    name = models.CharField(max_length=50) 
    address = models.CharField(max_length=80) 

class Restaurant(models.Model): 
    place = models.ForeignKey(Place) 
    serves_hot_dogs = models.BooleanField() 
    serves_pizza = models.BooleanField() 

,然后你可以这样做:

>>> p = Place.objects.get(id=12) 
>>> r = Restaurant(place=p) 
+1

型号继承线的东西从孩子到家长增加了一个隐含的OneToOne。但你很近。 – 2010-07-04 23:02:30

3

可惜模式“推广”像这样是有问题的。正确的方法是通过复制Place中的字段来创建新的Restaurant对象。您必须通过遍历Place._meta.get_fields_with_model()并查看字段属于哪个模型来执行此操作。我无法为您提供确切的代码,但如果您可以使用GPL代码,那么自修订版本bcd274ce7815以来它的版本号为transifex.txcommon.models

+0

任何机会,你可以提供一个链接到某个地方? – Fred 2010-07-05 00:08:13

+0

http://code.transifex.org/index.cgi/mainline/file/a9f391a5c9b8/transifex/txcommon/models.py#l62 – zellyn 2010-07-23 15:26:58

1

我遇到了同样的问题。我想我已经找到了一个很好的解决方案:

我定义我的餐厅模式通过使用这样三类:

class RestaurantBase(models.Model): 
    class Meta: 
     abstract = True 
    serves_hot_dogs = models.BooleanField(default=False) 
    serves_pizza = models.BooleanField(default=False) 

class Restaurant(Place, RestaurantBase): 
    pass 

class RestaurantStandalone(RestaurantBase): 
    class Meta: 
     managed = False 
     db_table = Restaurant._meta.db_table 
    place_ptr = models.OneToOneRelationship(Place) 

现在,如果我有,我想升级到餐厅的地方,我做以下:

p = Places.objects.get(id=3) 
r = RestaurantStandalone() 
r.place_ptr = p 
r.save() 

现在你的地方是餐厅

r = Restaurant.objects.filter(place_ptr=p) 
print(r.id) 
>>3 
0

正如我答道米Ÿ自己的问题here

我终于实现了沿

p = Place.objects.get(name="Bob's Cafe") 
Restaurant.objects.create(
    place_ptr = p.id, 
    serves_hot_dogs = True, 
    serves_pizza = False 
)