2010-10-06 39 views
1

我有以下的模型Django模型繼承問題。怎麼解決?

class Contact(models.Model): 
    lastname = models.CharField(max_length=200) 
    firstname = models.CharField(max_length=200) 
    ... 

class Journalist(Contact): 
    pass 

我有一個Contact在我的數據庫,我想,它成爲一個Journalist現有的應用程序。

在原始sql中,它看起來像insert into app_journalist values (25624);一樣簡單。在這個例子中,25624是現有聯繫人的ID。它似乎工作正常,Django應用程序似乎很高興。

但是,我想用django ORM做同樣的事情。我曾嘗試過多次認爲強迫記者編號(Journalist(id=25624)),但它創建了一個新的聯繫人,而不是鏈接到現有的聯繫人。

Django ORM有可能做到這一點嗎?怎麼樣?

在此先感謝您的幫助來解決,這是(在不改變你的模型結構)

回答

3

一種方式向Journalist實例的contact_ptr屬性設置爲適當Contact實例。對於例如

contact = Contact.objects.get(pk = 25624) 
journalist = Journalist(contact_ptr = contact) 
journalist.save() 

如果您首先查看錶app_journalist,這會變得更容易理解。它只有一列,contact_ptr_id。因此,當您執行insert into app_journalist values (25624)時,您在SQL級別上設置了contact_ptr_id = 25624。相應地,您應該在ORM級別設置contact_ptr = <instance of Contact>

更新

還有其他的方法來解決這個問題,但他們將需要改變現有的模型。作爲@ bugspy.net pointed out您可以使用通用關係。或者你可以聲明額外type字段指定聯繫人是否是記者,同事等

更新2

也看看這個demo snippet(和complete code),讓您使用多態繼承(SQLAlchemy已經這樣做了)。

更新3

由於@luc自己指出的(見下文評論)

journalist = Journalist(contact_ptr = contact) 
單獨

是不夠的。這將覆蓋contactfirstnamelastname""。爲了避免這種情況,您必須明確指定每個字段爲Journalist

+0

看來這是不夠的,因爲聯繫人的姓氏和名字被空值覆蓋。看來我也必須逐場複製。 的接觸.__ dict__: 如果= '_STATE': 記者.__字典__ [A] =接觸.__字典__ [A] 無論如何,感謝您的寶貴幫助 – luc 2010-10-06 12:05:54

2

Django的Contenttypes框架真的很方便。 你可以用它來代表不同的接觸類型:在模型級別

from django.db import models 
from django.contrib.contenttypes.models import ContentType 
from django.contrib.contenttypes import generic 

class Contact(models.Model): 
    lastname = models.CharField(max_length=200) 
    firstname = models.CharField(max_length=200) 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
+0

感謝。我會檢查內容類型框架 – luc 2010-10-06 12:07:18

0

繼承通常不是個好主意。大多數ORM讓你這樣做。大多數ORM甚至爲能夠做到而感到自豪。在模型層面,着名的「prefer composition over inheritance」比以往更加真實。

在你的情況,而不是說:「一位記者是一個人」,可以轉而說:「一個人有工作,在這種情況下是記者」。這將由一個由Job類組成的Person類來表示。其中一項工作可能是「記者」。

構圖方法可以讓你有一個人更換工作,甚至有多個工作。

當然,這不直接回答你的問題,但其他答案已經很不錯了!

+0

我同意你的看法,但它是一個現有的應用程序,改變模型並不容易 – luc 2010-10-06 11:18:31