Reputation: 7228
I want to order my QuerySet
in ascending order for this case:
PRIORITY_CHOICES = (
(1, "P1"),
(2, "P2"),
(3, "P3"),
(4, "P4"),
(5, "P5"),
)
class Task(models.Model):
name = models.CharField(max_length=255)
priority = models.PositiveIntegerField(choices=PRIORITY_CHOICES)
Now, since, the priority can accept None values. The problem is with ordering the Query set when I do this in my View code:
task_list = Task.objects.all().order_by("priority")
This returns me the query set with the objects arranged in ascending order of priority, with the None values first. I want the ascending list but I want to include the None values at the end. I have a huge database so, I am interested in accomplishing this at the database level.
Upvotes: 2
Views: 3764
Reputation: 87
you can do it simply like this in the Model like this
class ModelName(models.Model):
feild_1 = models.CharField( max_length=150)
feild_2 = models.CharField( max_length=150, blank=True, null=True)
class Meta:
ordering = [F('order').asc(nulls_last=True)]
Upvotes: 0
Reputation: 1407
You can change order to descending using queryset.order_by('-field')
(prepending "-" symbol), but there is no way in Django to tell how nulls should be sorted - it's database specific behavior. If using descending ordering still gives you null values first in your database - use queryset.extra(select={'order': 'custom_sql_function(priority)'}).order_by('order')
, where custom_sql_function
converts field to integer if it is null, and is specific for your database engine.
For faster performance you can create db index on function(field)
.
Upvotes: 1
Reputation: 8078
This is probably your best option.
import itertools
q = itertools.chain(
Task.objects.filter(priority__isnull=False).order_by("priority"),
Task.objects.filter(priority__isnull=True))
# Then you can iterate over your custom order
result = [(x.name, x.priority) for x in q]
Upvotes: 4