[Django]-Django complex ordering

0👍

I did this (on the QuerySet model):

def order_by_score(self):
    q = django.db.models.Q(ratings__score=1)
    documents_with_one_positive_rating = self.filter(q) # Annotation sees only
                                                        # the positive ratings
    documents_without_one_positive_rating = self.filter(~q)

    return (documents_with_one_positive_rating |
            documents_without_one_positive_rating).annotate(
                db_score=django.db.models.Count('ratings')
                ).order_by('-db_score')

Advantage is it still shows the documents without a positive rating.

3👍

This is a job for annotations.

from django.db.models import Count
Document.objects.filter(score=1).annotate(
             positive_votes=Count('vote__count')).order_by('positive_votes')

Edit

There isn’t really a way to do this without filtering, because that’s the way the underlying database operations work. But one not-so-nice way would be to do a separate query for all the documents not included in the original, and chain the two querysets together:

positive_docs = <query from above>
other_docs = Document.objects.exclude(id__in=positive_docs)
all_docs = itertools.chain(positive_docs, other_docs)

This would work as long as you don’t have millions of docs, but would break things like pagination.

Leave a comment