Sussagittikasusa
Sussagittikasusa

Reputation: 2581

How to do custom ordering of a Django queryset?

A little background about our specific problem ->

We are trying to build a Q & A site, much like Stackoverflow.
People can come and ask questions and other people reply.

So like SO (https://stackoverflow.com/questions) we have a questions page. Now the problem we're having is that we have this model :

class Questions(models.Models):   
    user = person
    question = CharField   
    number_of_replies = IntegerField  
    datetime = DateTime

The resultant queryset ( or list ) is determined by a combination of various factors like when it was posted, how many people replied to it, etc.

Since there's been confusion related to the question i'll clarify it -> This is the kind of output I'm looking for :

This is how the final order will be ->

  1. Question c posted 10 mins ago, 0 replies
  2. Question f posted 1 min ago, 2 replies
  3. Question b posted 5 mins ago, 1 reply etc.
    so there is no one-dimensional order, the order is a function of various parameters

Upvotes: 4

Views: 4020

Answers (2)

Sussagittikasusa
Sussagittikasusa

Reputation: 2581

One way of doing it is by defining a custom manager ->

https://docs.djangoproject.com/en/dev/topics/db/managers/#custom-managers-and-model-inheritance.

You can display the objects in any order you like. You can even return lists and self-defined dictionaries using the custom manager methods.

Upvotes: 2

lprsd
lprsd

Reputation: 87077

Each of your required clause represents a queryset.

Questions that are unanswered and posted in the last "X" mins:

unanswered_questions = Question.objects.filter(timestamp__gte=(now()-time(min=5))).annotate(answers_count=Count('Answer')).filter(answers_count=0)

And similarly.

Seems like you want to display a combination of a few querysets. You can use the itertools.chain method for that, to combine and display the result of a few querysets in your template, like:

combined_queryset = chain(recent_questions,unanswered_questions,...)

Keep in mind however that if there is an overlapping condition on these querysets, some questions can get repeated. You may avoid that by explicitly converting the result of the one queryset in the next ones, or you may convert queryset into list and let the set.union type take care of possible duplicates.

Upvotes: 1

Related Questions