2014-03-31 26 views
1

我想要做的是在創建ScanEvent實例時增加卡的點數。 我有以下型號:如何使用信號更新Django中的另一個對象?

class Card(models.Model): 
    # some attributes 

class Points(models.Model): 
    benef_card = models.ForeignKey(Card, related_name='points') 
    at_owner = models.ForeignKey(OwnerProfile) 
    nb_current_points = models.PositiveIntegerField(default=0) 

class ScanEvent(Event): 
    scanned_card = models.ForeignKey(Card) 
    scanned_at_owner = models.ForeignKey(OwnerProfile) 
    won_points = models.PositiveIntegerField(default=1) 

    # This method is called with a post_save signal to add points to a card 
    def add_points_to_card(sender, instance, **kwargs): 
     pts = instance.scanned_card.points.get(at_owner=instance.scanned_at_owner) 
     pts.nb_current_points += instance.won_points 
     pts.save() 

# At the end of models.py 
signals.post_save.connect(ScanEvent.add_points_to_card, 
     sender=ScanEvent) 

在一個簡單的Django殼,當我試試這個:

card = Card.objects.get(pk=2) 
event = ScanEvent(scanned_card=card) 
ownr = OwnerProfile.objects.get(pk=1); 
event.save() # will call add_points_to_card() 

我沒有得到任何錯誤,但不會更新點(這是因爲信號不叫) (它工作時,我重寫save()方法思想)

謝謝。

+0

請出示您所使用的連接信號到底是什麼代碼。 –

+0

完成。不知道它是連接信號的正確位置(但錯誤似乎與此無關)。 –

回答

1

不確定您的模型是否正確。通過指向卡的外鍵,這意味着每個卡都有多個點實例。所以當你有一個Card對象時,你不能直接訪問這些點:card.points是與這張卡相關的所有Points對象的查詢集。

要麼你需要確定哪個相關點是你的意思,或者改變你的模型。可能使用OneToOne字段而不是ForeignKey會更合適:那麼您只有一個Points實例,並且card.points將按照您的預期引用該實例,然後您將能夠訪問它的nb_current_points值。

編輯

遞歸錯誤是因爲你連接你的處理程序,以保存信號所有類,而不僅僅是ScanEvent。註冊時,您應該確保指定sender參數:

signals.post_save.connect(add_points_to_card, sender=ScanEvent) 

請注意,您必須搬完了ScanEvent類的,否則你會得到錯誤的名稱。

+0

哦,我的錯誤對不起:我刪除了一些字段,以使它更容易在StackOverflow,但ForeignKey是故意的,因爲每個現有ownerProfile(請參閱更新的代碼)存在一個Points實例。 –

+0

感謝您的編輯。遞歸的另一個原因是因爲我保存了「實例」而不是「點」。添加ScanEvent作爲發件人使我有一個'NameError:名稱'ScanEvent'沒有定義':( –

1

在您的模型中,卡片可能有幾個關聯點。這就是爲什麼instance.scanned_card.points是一個RelatedManager,而不是一個Point。 試試這個:

def add_points_to_card(sender, instance, **kwargs): 
    for points in instance.scanned_card.points.all(): 
     points.nb_current_points += instance.won_points 
+0

感謝renobryce和@Daniel Roseman這幫助我明白,我調用了queryset而不是對象的方法。不同(請參閱更新後的文章) –

相關問題