Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do custom ordering of a Django queryset?

Tags:

python

django

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
like image 247
Sussagittikasusa Avatar asked Oct 29 '25 16:10

Sussagittikasusa


2 Answers

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.

like image 91
Sussagittikasusa Avatar answered Oct 31 '25 06:10

Sussagittikasusa


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.

like image 40
lprsd Avatar answered Oct 31 '25 05:10

lprsd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!