2014-03-31 1 views
1

내가 원하는 것은 ScanEvent 인스턴스가 생성 될 때 카드의 점수를 높이는 것입니다.신호를 사용하여 장고에서 다른 객체를 업데이트하는 방법은 무엇입니까?

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() 

나는 오류를 얻을 수 없지만 포인트는 신호가 호출되지 않습니다 때문입니다 (업데이트되지 않습니다 : 내가하려고 할 때이 간단한 장고 쉘에서

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) 

: 나는 다음과 같은 모델을 가지고) (save() 메소드 생각을 무시할 때 작동 함)

고마워.

+0

신호 연결에 사용하는 코드를 정확하게 표시하십시오. –

+0

완료. 확실하지 신호를 연결할 수있는 장소 (하지만 오류가 관련이없는 것 같아). –

답변

1

모델이 맞는지 확실하지 않습니다. 포인트 대 카드의 ForeignKey를 사용하면 각 카드에 복수 포인트 인스턴스가 있음을 의미합니다. 따라서 Card 객체를 가지고있을 때는 직접 포인트에 액세스 할 수 없습니다. card.points은이 카드와 관련된 모든 Points 객체의 쿼리 세트입니다.

당신은 어떤 관련 포인트가 당신이 의미하는 것인지를 결정하거나 모델을 변경해야합니다. 아마도 ForeignKey 대신 OneToOne 필드를 사용하는 것이 더 적절합니다. 그러면 단일 Points 인스턴스 만 있고 card.points은 예상대로 해당 인스턴스를 참조하므로 nb_current_points 값에 액세스 할 수 있습니다. 당신이 모든 클래스뿐 아니라 ScanEvent의 저장 신호 처리기를 부착했기 때문에

편집

재귀 오류입니다. 를 등록 할 때 당신은 sender 매개 변수를 지정해야한다 : 당신이 그렇지 않으면 당신은 이름 오류를 얻을거야 ScanEvent 클래스의 밖으로 사람들을 이동해야합니다

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

참고.

+0

오, 제 실수 실수 : StackOverflow에서 쉽게하기 위해 일부 필드를 제거했지만, ForeignKey는 의도적입니다. 왜냐하면 Points 인스턴스가 각각의 기존 ownerProfile에 존재할 수 있기 때문입니다 (업데이트 된 코드 참조). –

+0

수정 해 주셔서 감사합니다. 재귀의 또 다른 이유는 "pts"대신 "instance"를 저장했기 때문입니다. ScanEvent를 보낸 사람으로 추가하면 NameError : name 'ScanEvent'is not defined '라는 메시지가 나타납니다. ( –

1

모델에 따라 카드에 여러 개의 포인트가 연관 될 수 있습니다. 이것이 instance.scanned_card.points가 Point가 아닌 RelatedManager 인 이유입니다. 시험해보기 :

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 덕분에 객체 대신 쿼리 세트에서 메소드를 호출했음을 이해할 수있었습니다. 다른 (업데이트 된 게시물 참조) –

관련 문제