2016-10-31 33 views
0

我正在將項目從django 1.8升級到1.10,它看起來像Django已經改進了外鍵和模型繼承之間最終名稱衝突的檢查。 這顯然是一件好事,但我需要升級的projet是一個很大的,它將是一個地獄重新命名模型。Django繼承和父對象相關的名稱

讓我解釋一下這個問題:我叫Parent,許多兒童被連接在一起,像這樣一個基類:

class Parent(models.Model): 
    title = models.CharField(max_length=10) 


class ChildA(Parent): 
    description = models.TextField() 


class ChildB(Parent): 
    description = models.TextField() 
    childa = models.ForeignKey(ChildA) 

這裏的衝突是一個childb對象2「childa」屬性:

  • 的 「childa」 ForeignKey的
  • 由ChildA模型繼承的情況下(因爲childb也有parent屬性)。

這裏的2個顯而易見的解決方案是:

  • 重命名ForeignKey的ChildB.childaChildB.somethingelse
  • ChildA模型重命名爲別的東西。

這兩種解決方案的成本很高,可能會引入新的錯誤。 所以我想知道:是否可以重命名繼承對象的反向相關名稱?

例如:

p = Parent.objects.get(pk=1) 
print p.childa_child # Hit the ChildA instance 

我不知道如果我很清楚,但我會繼續這個問題,是最新的。

==== ====編輯

更簡潔,如果我有2種型號class Parent(models.Model)class Child(Parent),動態屬性創建parent.child

是否可以在不觸及類名的情況下編輯此屬性名稱?

回答

2

多表繼承會在基礎模型和子類之間創建一個隱含的OneToOneField字段。

Django允許您通過明確設置一對一字段來修改此關係。

class Parent(models.Model): 
    title = models.CharField(max_length=10) 


class ChildA(Parent): 
    parent = models.OneToOneField(to=Parent, parent_link=True) 
    description = models.TextField() 


class ChildB(Parent): 
    parent = models.OneToOneField(to=Parent, parent_link=True) 
    description = models.TextField() 
    childa = models.ForeignKey(ChildA) 

這裏最重要的一點是parent_link=True參數,它告訴Django使用這個字段聲明用於管理與這兩款車型的多表繼承。回答

class ChildA(Parent): 
    parent = models.OneToOneField(to=Parent, parent_link=True, related_name='child_a_here') 
    description = models.TextField() 


class ChildB(Parent): 
    parent = models.OneToOneField(to=Parent, parent_link=True, related_name='child_b_here') 
    description = models.TextField() 
    childa = models.ForeignKey(ChildA) 
+0

完全是它!謝謝。 這裏也是鏈接到文檔中的參考: https://docs.djangoproject.com/en/1.10/topics/db/models/#specifying-the-parent-link-field – martync

0

我對ChildB有兩個ChildA鏈接有點困惑,它看起來像是從模型中遺漏了一些關係字段?無論如何,我認爲你正在尋找的是related_name參數。

所以有:

class ChildB(Parent): 
    description = models.TextField() 
    childa = models.ForeignKey(ChildA, related_name='b_children') 

你可以做一個查詢,如下所示:

a = ChildA.objects.get(id=1) 
print(a.b_children) 

您還可能有興趣在abstract models

+0

感謝:

所以,你現在可以設置related_name='+'防止Django的從創建一個反向的關係,也可以設置related_name以更加獨特的名字。 這不是問題。我發現Django票據涉及到這一點:https://code.djangoproject.com/ticket/17673 父模型有2個屬性「childa」,在django 1.8之前,它被引用來影響其中一個屬性,但與Django的1.9 +它引發了SystemCheckError。 p = Parent.objects.get(pk = 1) print p.childa#它是否應該碰到ChildB子項或ChildB子項的childa屬性? – martync

+0

我編輯了最初的帖子來添加一個更簡單的例子。 – martync