NewToJS
NewToJS

Reputation: 2101

Django: How to order a queryset and move some items to end of the queryset

I have a queryset in my Django application:

databytes_all = DataByte.objects

Each item in the databytes_all queryset has many attributes but one of them is publish_date.

I'd like to order the queryset by publish_date, however if publish_date is None, I'd like the item to be at the end of the queryset.

This is what I'm trying but it's not working:

databytes_all = DataByte.objects

Make a queryset: filter out all of the publish dates that are None

no_date = databytes_all.filter(publish_date=None)

Make anohther queryset: exclude all of the items where publish date is none, then order the remaining items by publish date

databytes_with_date = databytes_all.order_by('-publish_date').exclude(publish_date=None)

Now combine the two querysets (however this doesnt work- the items with no publish date are first in the list when I want them to be last)

databytes = databytes_with_date | no_date 

Upvotes: 3

Views: 909

Answers (2)

maghsood026
maghsood026

Reputation: 298

In Django, you can combine a lot of QuerySet using chain try this:

from itertools import chain

...

combined_results = list(chain(databytes_with_date, no_date))

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477607

You do not need to filter, you can specify that the NULL should be last with:

from django.db.models import F

databytes_all.order_by(F('publish_date').desc(nulls_last=True))

We here thus make use of an F object [Django-doc] where we call the .desc(…) method [Django-doc]. This method has a nulls_last=… parameter that we can use to specify that items with NULL should be selected as the last records.

This will sort with:

SELECT …
FROM …
ORDER BY publish_date IS NULL, publish_date DESC

since False/0 is considered less than True/1, it will thus move the items with publish_date to the bottom of the records you retrieve.

Upvotes: 4

Related Questions