compute model field by related field

69 views
Skip to first unread message

omar ahmed

unread,
Apr 16, 2019, 6:19:34 PM4/16/19
to Django users
hello ... i have two models "Club" class and "Match" class and it has foreign key to Club
now i want to increment "won" field (or draw or lost) in "Club" class by "score_local" and "score_visitor" in "Match" class ..
how can i do this
class Club(models.Model):
name = models.CharField(max_length=100)
won = models.IntegerField(default=1)
draw = models.IntegerField(default=1)
lost = models.IntegerField()
goal_for = models.IntegerField()
goal_against = models.IntegerField()


class Match(models.Model):
play_date = models.DateTimeField('play date')
club_visitor = models.ForeignKey(Club, on_delete=models.CASCADE, related_name='match_club_visitor')
club_local = models.ForeignKey(Club, on_delete=models.CASCADE, related_name='match_club_local')
score_visitor = models.IntegerField()
score_local = models.IntegerField()

Makori Breens

unread,
Apr 16, 2019, 8:37:54 PM4/16/19
to django...@googlegroups.com
Implement rest framework

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/33e234c0-22d1-43aa-be66-fd2149cd085d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Derek

unread,
Apr 17, 2019, 1:26:22 PM4/17/19
to Django users
1. Add a "winner" field to your Match
2. Implement a post_save  signal for the Match model that updates the "won" or "lost" fields for each Club in the match (simple if/then logic based on winner).

PS I think the default values for "won" and "lost" for a Club should be "0" and not "1".

omar ahmed

unread,
Apr 18, 2019, 12:09:41 PM4/18/19
to Django users
thank you for response , derek
but how can i increment 'win' 'lost' or 'draw' Club fields by 'winner' Match field

Derek

unread,
Apr 20, 2019, 7:09:01 AM4/20/19
to Django users
That should just require a basic if/then logic test; "get" the correct Club object, update the win/loss field and save the Club. Repeat for both Clubs.

omar ahmed

unread,
Apr 22, 2019, 2:22:19 PM4/22/19
to Django users
i put this function in "Match" class :
def points(self):
if self.score_local > self.score_visitor:
return (self.club_local.won)+1 and (self.club_visitor.lost)+1
elif self.score_local < self.score_visitor:
return (self.club_local.lost)+1 and (self.club_visitor.won)+1
else:
return (self.club_local.draw)+1 and (self.club_visitor.draw)+1
and i want it to update fields and 'CalcPoints' function in "Club" class
class Club(models.Model):
...
def CalcPoints(self):
return self.won*3 + self.draw

but until now it does not update objects (( how can i use post_save here ))

Derek

unread,
Apr 23, 2019, 1:27:28 PM4/23/19
to Django users
You need to use Django signals to provide a custom "post_save".  There is a good tutorial here:
https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html

omar ahmed

unread,
Apr 23, 2019, 2:31:43 PM4/23/19
to Django users
yes i studied this tutorial before and i added this function to "Club" class (( Receiver function class )) but it does not affect fields
def teampoints( sender, instance, **kwargs):
if instance.score_local > instance.score_visitor:
return instance.club_local.won +1 and instance.club_visitor.lost + 1
elif instance.score_local < instance.score_visitor:
return instance.club_local.lost + 1 and instance.club_visitor.won + 1
else:
return instance.club_local.draw + 1 and instance.club_visitor.draw + 1

Derek

unread,
Apr 24, 2019, 6:13:05 AM4/24/19
to Django users
Did you add the required decorator before this function?  (The function is not part of the class; its a standalone appearing in the same module.)

Also, you generally don't put returns in the post_save function: but you do need to call save() on the model instance.

omar ahmed

unread,
Apr 24, 2019, 12:30:39 PM4/24/19
to Django users
ok Derek i used save() instead of return and it works now
thank you very much
@receiver(post_save, sender=Match)
def update_club_score(instance, sender, **kwargs):
# club local won
if instance.score_local > instance.score_visitor:
instance.club_local.won += 1
instance.club_local.save()
instance.club_visitor.lost += 1
instance.club_visitor.save()
# club local lost
if instance.score_local < instance.score_visitor:
instance.club_local.lost += 1
instance.club_local.save()
instance.club_visitor.won += 1
instance.club_visitor.save()
# draw
if instance.score_local == instance.score_visitor:
instance.club_local.draw += 1
instance.club_local.save()
instance.club_visitor.draw += 1
instance.club_visitor.save()
Reply all
Reply to author
Forward
0 new messages