0

I have the following models:

class Question(models.Model):
    Title = models.CharField(max_length=250)
    User = models.ForeignKey(User)

    def GetVotes(self):
        return Vote.objects.filter(Question=self).aggregate(Sum('Vote'))['Vote__sum']

class Vote(models.Model):
    Question = models.ForeignKey(Question)
    User = models.ForeignKey(User)
    Vote = models.IntegerField()

And as can be seen from the Question model I use a custom method to calculate the votes for each question. I do that as I would like to separate the votes from the actual question, and hence I wouldn't want to keep a vote counter in the Question model as well as in Vote as this will be hard to maintain later.

According to good design, information that can be calculated shouldn't be stored.

I can now find the votes of each question just fine, but the problem comes down to the order_by. I would like to get all the questions, and order them by their votes. As far as I am aware, that is not possible as the order_by() is down to the database level, where my method is not at a database level.

I would like to find a nice way to do that without using other technique than ORM is that possible?

Edit:
It looks like there is no nice way using ORM so I have implemented using sorted.

Rafael
  • 7,002
  • 5
  • 43
  • 52
  • I thin annotate should do what you want, see this answer: http://stackoverflow.com/questions/2501149/order-by-count-of-a-foreignkey-field?rq=1 – ger.s.brett Mar 06 '16 at 20:00
  • Thank you for your comment @ger.s.brett. I have faced this solution, before asking the question, but the only difficulty I found with this solution is that there should be a `join` between the two models so that I can achieve that. – Rafael Mar 06 '16 at 20:02

2 Answers2

1

There is no way to do that since order_by is applied at database level.

But you have two alternatives:

  1. Create a field to store the calculated value and override write method so that you can calculate the value there
  2. Sort the queryset as shown in this answer
Community
  • 1
  • 1
E Rodriguez
  • 323
  • 1
  • 2
  • 14
  • Thank you for your answer. I was thinking of a `view` table instead of storing the data in the `Question` model, but I am not sure if that is possible with Django. – Rafael Mar 06 '16 at 19:58
1

You can annotate the data you're looking to sort on and then sort by that value.

Question.objects.annotate(vote_count=Sum('vote_set__vote')).order_by('vote_count')

brechin
  • 569
  • 4
  • 7