Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order a Django queryset in ascending order but with 0-valued items at the end

I am new to python, django. What I am trying to do is that I have a model defined as products which has two columns: name and price.

name    price
pen      20
paper    30
eraser   0

I am trying to sort them using the following code:

Product.objects.all().order_by('-price')

This sorts the values as 0,20,30.

The model code is

class Product(models.Model):
    name = models.CharField(max_length=100, blank=True, null=True)
    price = models.IntegerField('Price', blank=True, null=True)

What I am trying to achieve is to sort it as 20,30,0 with 0 being appended at the end.

Is there any function with which I can achieve it?

like image 969
Roan Avatar asked Oct 20 '15 11:10

Roan


People also ask

Can we order data in descending order in Django?

if you want to select by Descending just add minus operator before the attribute field or if you want to select by Ascending no need minus operator.

How does QuerySet work in Django?

A QuerySet represents a collection of objects from your database. It can have zero, one or many filters. Filters narrow down the query results based on the given parameters. In SQL terms, a QuerySet equates to a SELECT statement, and a filter is a limiting clause such as WHERE or LIMIT.


2 Answers

You could order by a calculated value in case you really want to do everything on the DB level. This should work:

Product.objects.all().order_by(\
        Case(When(price=0, then=Value(MAX_INT)), default=F('price')))

Where MAX_INT=2147483647 is the value of a 32 bit signed integer which is safe on all Django-supported DBs.

like image 139
Ivan Avatar answered Oct 29 '22 22:10

Ivan


The following could work, it's not the nicest code to implement but for your special case I think this is the easy way to do it using queryset directly, otherwise you can think about implementing it in Python(sorted or other builtin functions)

qs = Product.objects.exclude(price=0).order_by('-price') | Product.objects.filter(price=0)
like image 25
Mounir Avatar answered Oct 29 '22 21:10

Mounir