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

牧云@^-^@ 提交于 2020-01-01 08:05:18

问题


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

class Product(models.Model):
    price = models.DecimalField(max_digits=8, decimal_places=2)
    sale_price = models.DecimalField(max_digits=10, blank=True, null=True, decimal_places=2)

For the majority of products, price will be filled but sale_price will not be. So, I can order products by price like so:

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

However, some products will have a sale_price, and I can't find a way to order these neatly so that the sale price interleaves with the normal price. If I try ordering by both fields:

Product.objects.order_by('sale_price','price')

...then all the products that aren't on sale appear together, followed by all that are, instead of interleaving the prices.

Does this make sense? Does anyone have a way to solve this?

Thanks!


回答1:


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




回答2:


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')


来源:https://stackoverflow.com/questions/6001231/django-order-items-by-two-fields-but-ignoring-them-if-theyre-zero

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!