Reputation: 2101
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
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
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