2009-07-02 41 views
1

如何使外鍵引用回對象本身?我想:非空foreignKey('self')

Alias(MyBaseModel): 
    type = models.ForeignKey('self') 

a = Alias() 
a.type = a 
a.save() 

但是當我運行它:

(1048, "Column 'type_id' cannot be null") 

我不想類型爲空,我希望它包含它自己的ID。我有大量的對象,但只有1個回到自身,所以我真的不想讓它變爲空。想法?

+0

put()是做什麼的?我以前從來沒有見過。 – 2009-07-02 23:10:27

+0

對不起,它是保存的同義詞。更改 – 2009-07-02 23:25:42

+0

而不是類型,你可能想要使用非python關鍵字:-) – drozzy 2009-07-03 14:52:04

回答

4

問題是,當你做a.type = a時,數據庫中還沒有a,因此它沒有pk。

解決此問題的一種方法是保存兩次,首先將其保存到數據庫中,引用已存在於數據庫中的虛擬對象,然後在從數據庫中獲取該虛擬對象後再保存它。與此有關的一個問題是,首先實際上將這樣的對象放入數據庫中存在雞和蛋的問題。我通過創建每次使用sync-db時運行的fixture來處理這個問題,這樣一個對象就存在並且是有效的。

另一種方法是放鬆非空的約束,並努力讓他們分配。無論哪種方式,插入這樣的表格總是會很痛苦,因爲如果沒有首先插入就不能使用PK,並且不能在沒有在參考字段中使用鍵的情況下插入PK,無論ORM或數據庫或任何東西。

的替代解決方案是打破循環依賴,並做一些事情,如:

AliasType(django.db.Model): 
    pass 

Alias(MyBaseModel): 
    type = models.ForeignKey(AliasType) 

a = Alias() 
a_t = AliasType() 
a_t.save() 
a.type = a_t 
a.save() 

您仍然可以通過使用Django的非常聰明的存取得到有用的信息,

AliasType.objects.all()[0].alias_set 

它可以讓你回來到原始的Alias對象,而沒有明確的鏈接。

1

不應該您的類型字段爲null = True,空白= True?否則,你的基本情況是什麼? 我的意思是如果你在db中只有一個對象它是什麼類型的?

讓對象循環到自身上可以通過採用一個空的類型字段意味着 - - 該對象指的是它自己!

如果類型字段不是空的,這意味着它指的是另一個別名對象,它只是一個桃子。

你的問題在算法層面上沒有意義(除非我錯過了某些東西),那麼如何讓它在db中工作?

Alias(MyBaseModel): 
    type = models.ForeignKey('self', blank=True, null=True) 

a = Alias() 
a.save() 
# Now a refers to itself 

b = Alias() 
b.type = a 
b.save() 
# b does not refer to itself, but rather a 

我知道我重新定義了這個問題,所以很抱歉,如果那不是你以後的事!乾杯。

0
set null=true , blank=true in your code 
like, 

Alias(MyBaseModel): 
    type = models.ForeignKey('self' , blank=True, null=True) 

a = Alias() 
a.type = a 
a.save()