2010-09-14 100 views
7

我有以下的多表繼承的情況:Django - 刪除對象,保留父對象?

from django.db import Models 

class Partner(models.Model): 
    # this model contains common data for companies and persons 
    code = models.CharField() 
    name = models.CharField() 

class Person(Partner): 
    # some person-specific data 
    ssn = models.CharField() 

class Company(Partner): 
    # some company-specific data 
    tax_no = models.CharField() 

我怎麼能一個公司實例轉換爲一個,反之亦然?
比方說,有人錯誤地創造了個人的詳細信息的公司如:

company = Company(name="John Smith", tax_no="<some-ssn-#>") 

我想所有的錯誤公司對象(的意思是人)轉換爲對象,保持所有相關記錄(我有模型與FKs到合作伙伴模型,所以重要的是保持相同的partner_ptr價值)。我可以做這樣的事情:

person = Person(name=company.name, ssn=company.tax_no, partner_ptr=company.partner_ptr) 

到目前爲止好,但有可能以刪除不再需要的公司對象?刪除公司對象也將刪除它的父項合作伙伴對象(和任何與合作伙伴有關的,包括新創建的個人對象)。

有什麼建議嗎?謝謝!

P.S .:這是一個已部署的系統,其中包含大量數據,不可能重新設計整個Partner-Person-Company繼承概念。

回答

4

解決這個問題的方法之一是首先爲每個等待刪除的公司添加一個虛擬Partner。之後,您可以將所有不需要的Company實例的partner_ptr更新爲適當的虛擬夥伴實例。最後你可以刪除所有的公司。

當然,您可以使用South來做到這一點。

更新

做了一些初步的測試,這個工程。我正在使用Django 1.2.1。

I have tried this, it's not possible: In 1 : Company.objects.get(pk=7924) Out 1 : In [2]: c.partner_ptr = Partner() In [3]: c.pk In [4]: c.delete() AssertionError: Company object can't be deleted because its partner_ptr_id attribute is set to None. Setting the partner_ptr instance to a dummy one changes the company's PK and it's not the Company.

你必須附加一個新Partner然後保存公司。然後你可以安全地刪除它。

所以:

company = Company.objects.get(pk=7924) 
dummy_partner = Partner(code = "dummy", name = "dummy") 
company.partner_ptr = dummy_partner 
company.save() 
company.delete() 
+0

我試圖此,這是不可能的: 在[1]:Company.objects.get(PK = 7924) 輸出[1]:<公司:約翰·史密斯> 在[2]:= c.partner_ptr夥伴() 在[3]:c.pk 在[4]:c.delete() 的AssertionError:公司對象不能因爲其partner_ptr_id刪除屬性設置爲無。 將partner_ptr實例設置爲虛擬實例會更改公司的PK,而不是公司。 – Alexander 2010-09-14 17:27:17

+0

@Alexander:查看我更新的答案。刪除之前,您必須先保存公司。 – 2010-09-14 17:31:31

+0

非常感謝Manoj,在拯救了它的公司之後。根據SQL日誌,它只刪除公司表中的內容:2010-09-14 20:43:49 EEST LOG:語句:DELETE FROM「partners_company」WHERE「partner_ptr_id」IN(7924) 2010-09-14 20 :43:49 EEST LOG:語句:DELETE FROM「partners_partner」WHERE「id」IN(NULL) – Alexander 2010-09-14 17:48:25