2010-07-04 208 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 
)