2017-02-27 67 views
0

我有兩個孩子Django的ORM和pre_init信號

class MyChild1(models.Model): 
    attr1 = models.CharField(default='default value') 

class MyChild2(models.Model): 
    pass 

class MyParent(models.Model): 
    child1 = models.ForeignKey(Child1) 
    child2 = models.ForeignKey(Child2) 

在我的包中的類,我需要attR1位的價值 - 以確保它存在,我初始化母公司有信號:

def init_my_parent(sender, *args, **kwargs): 
    child1 = MyChild1() 
    child2 = MyChild2() 

signals.pre_init.connect(init_my_parent,sender=MyParent) 

這似乎工作正常,以確保child1和child2總是實例化。然而,即使我手動設置child1和的child2(my_parent.child1 = child1等),child1_idchild2_id不要設置和DB引發錯誤

django.db.utils.IntegrityError: NOT NULL constraint failed: myparent.child1 

我不知道是什麼原因造成這種現象?不知何故連接該信號導致了一個問題,但我不知道爲什麼。這裏是一個腳本類似於我使用:

c1 = MyChild1() 
c2 = MyChild2() 
c1.save() 
c2.save() 
p = MyParent() 
p.child1 = c1 
p.child2 = c2 
p.save() 
# Error thrown 

無論在init_my_parent設定值應高於覆蓋,因此一切都應該工作一樣,如果信號功能是不存在?

+0

「在init_my_parent中設置的值都應該被覆蓋,因此它不應該有效果嗎?」 - 他們爲什麼/如何被覆蓋? – ChidG

+0

在你的信號中,你正在實例化兩個新的子對象,但它們沒有被保存到數據庫,所以它們不會有'id'屬性。 – ChidG

+0

我已經用我用來覆蓋這些值的腳本添加了一些細節到最後。 – nven

回答

1

問題是pre_init信號不帶實例參數,所以你正在編輯實際類(sender)。嘗試使用post_init信號這需要instance參數,所以你可以改變它:

def init_my_parent(sender, instance, *args, **kwargs): 
    if not hasattr(instance,'child1'): 
     instance.child1 = MyChild1() 
     instance.child1.save() 
    if not hasattr(instance,'child2'): 
     instance.child2 = MyChild2() 
     instance.child2.save() 

signals.post_init.connect(init_my_parent, sender=MyParent) 
+0

我認爲你的意思是'sender.child1 = MyChild1()'等? 由於它是一個pre init信號,它們應該在該信號中首先被實例化,然後用我創建的新實例替換。即使如此,我也嘗試了這一點,併發生同樣的錯誤。 – nven

+0

啊哈,我看到了什麼問題。我已經更新了答案。 –

+0

啊,這很有道理。謝謝!我想我可以檢查*參數,看看這些變量是否在構造函數中定義 - 如果它們是使用這些變量? 我的查詢似乎沒有返回正確的值,但這可能是無關的。 – nven

0
class MyChild1(models.Model): 
    attr1 = models.CharField(default='default value', max_length=100) 

class MyChild2(models.Model): 
    pass 

class MyParent(models.Model): 
    child1 = models.ForeignKey(MyChild1) 
    child2 = models.ForeignKey(MyChild2 

使用類,而不是閃避,那麼它會好起來的。

+0

對不起,這只是一個錯字,我絕對使用類。將更新 – nven