Django order items by two fields, but ignoring them if they're zero

前端 未结 2 2050
终归单人心
终归单人心 2021-02-12 19:12

I have the following model (greatly simplified for the purposes of this question):

class Product(models.Model):
    price = models.DecimalField(max_digits=8, dec         


        
相关标签:
2条回答
  • 2021-02-12 19:22

    You could use the extra() QuerySet method to create an extra field in your query using the COALESCE function in SQL, which returns the first non-NULL value it's passed.

    Product.objects.extra(select={"current_price":"COALESCE(sale_price, price)"}, order_by=["-current_price"])
    

    You have to put your order_by in the extra() call as the extra manual field "doesn't really exist" as far as the rest of the ORM is concerned, but the syntax is the same as normal Django order_by()s.

    See the extra() documentation here: http://docs.djangoproject.com/en/1.3/ref/models/querysets/#extra

    0 讨论(0)
  • 2021-02-12 19:32

    If you stumble upon this requirement and happen to be using Django 1.8 and higher, you can use django.db.models.functions.Coalesce for a slightly nicer, cross db-engine, solution:

    from django.db.models.functions import Coalesce
    
    Product.objects.annotate(
        current_price=Coalesce('sale_price', 'price')
    ).order_by('-current_price')
    
    0 讨论(0)
提交回复
热议问题