views:

775

answers:

2

Hey I want to sort objects based on a computed value in django... how do I do it?

Here is an example User profile model based on stack overflow that explains my predicament:

class Profile(models.Model):
    user = models.ForeignKey(User)

    def get_reputation():
        ... 
        return reputation
    reputation = property(get_reputation)

So, say I want to sort users by reputation. How do I do that? I know you can't just do this:

Profile.objects.order_by("-reputation")

Thanks for your help everyone :)

+8  A: 

Since your calculation code exists only within Python, you have to perform the sorting in Python as well:

sorted (Profile.objects.all (), key = lambda p: p.reputation)
John Millikin
hey, this is the answer to the question I asked, but I accepted the other one because it solved the problem I have... specifically S.Lott's comment. I upmodded your answer though :)
Jiaaro
is there a way to make this return a queryset instead of a regular python list (or convert a list to a queryset)?
Jiaaro
That seems like a bit heavy to ask in a comment, so I moved it to it's own question: http://stackoverflow.com/questions/1058135/django-convert-a-list-back-to-a-queryset
Jiaaro
+4  A: 

If you need to do the sorting in the database (because you have lots of records, and need to e.g. paginate them), the only real option is to turn reputation into a denormalized field.

Carl Meyer
+1: simply override save() to keep this field up-to-date.
S.Lott
I decided to use the post-save signal rather than overriding save()... are there any potential gotchas I should know about with that approach?
Jiaaro
If you want to use signals, I'd recommend pre_save rather than post_save. To keep a denormalized field up to date with post_save means you have to do two UPDATE queries where one would suffice.
Carl Meyer
@Carl Meyer Thanks Carl... I'm actually updating a different model than the one that's being saved, but thanks... I think the rule of thumb is use post-save to update a different model from the one you're saving, and pre-save if it's the same model, no?
Jiaaro
@Jim Robert Sure, in that case you want post_save to ensure you only do the update if the model successfully saved.
Carl Meyer