0

I have three models (Django 1.6.5):

class Vote(models.Model):
    voter  = models.ForeignKey(UserSettings)
    answer = models.ForeignKey(Answer)
    rating = models.IntegerField()

class Answer(models.Model):
    content = models.CharField(max_length=255)

class UserSettings(models.Model): 
    user = models.OneToOneField(User, related_name='settings')
    weight = models.FloatField(default=1.0)

Basically, a user (voter) can vote for an answer by giving a rating. I know how to sum the ratings by answer:

Vote.objects.all().values('answer').annotate(score=Sum('rating'))

The only subtlety is that each voter has a weight (all voters are not equal!) and I want to sum each product rating*weight. I know (from here) that something like that can be done:

Sum('id',field="field1*field2")

and it would work well if my 2 fields are in the same model but it doesn't work if they are not. In other words, command:

Vote.objects.all().values('answer').annotate(score=Sum('id',field="rating*voter__weight"))

does not work. Any help greatly appreciated!

Community
  • 1
  • 1
Patrick
  • 2,577
  • 6
  • 30
  • 53

1 Answers1

0

The problem is that we need the join with another table (in this case UserSettings), so we need "force" the join.

q = Vote.objects.all().filter(voter__settings__weight__gt=0).values("answer").annotate(Sum('id', field='rating*weight'))

To force the join I used the filter clause (In fact I suppose that all the users have a weight greater than 0) but is just used to force the join. Then you can use the weight field.

PD: I think that this problem is solved in the latest version of Django with Conditional Expressions: https://docs.djangoproject.com/es/1.10/ref/models/conditional-expressions/

Marcos Schroh
  • 445
  • 3
  • 11