Django упорядочивает элементы по двум полям, но игнорирует их, если они равны нулю
у меня есть следующая модель (значительно упрощенная для целей этого вопроса):
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)
для большинства продуктов, цена будет заполнена, но sale_price не будет. Итак, я могу заказать продукцию по цене так:
Product.objects.order_by('price')
Product.objects.order_by('-price')
однако некоторые продукты будут иметь sale_price, и я не могу найти способ заказать их аккуратно, чтобы цена продажи чередовалась с нормальной ценой. Если я попробую заказать по обоим полям:
Product.objects.order_by('sale_price','price')
...тогда все продукты, которые не продаются, появляются вместе, а затем все, что есть, вместо того, чтобы чередовать цены.
имеет ли это смысл? У кого-нибудь есть способ решить эту проблему?
спасибо!
2 ответов
вы можете использовать метод extra() QuerySet для создания дополнительного поля в вашем запросе, используя функцию COALESCE в SQL, которая возвращает первое ненулевое значение, которое она передала.
Product.objects.extra(select={"current_price":"COALESCE(sale_price, price)"}, order_by=["-current_price"])
вы должны поместить свой order_by в вызов extra (), поскольку дополнительное ручное поле "на самом деле не существует", насколько это касается остальной части ORM, но синтаксис такой же, как обычный Django order_by () s.
см. дополнительную документацию () здесь: http://docs.djangoproject.com/en/1.3/ref/models/querysets/#extra
Если вы наткнетесь на это требование, и с помощью Джанго 1.8 и выше, вы можете использовать django.db.models.functions.Coalesce
для немного приятнее, крест db-engine, решение:
from django.db.models.functions import Coalesce
Product.objects.annotate(
current_price=Coalesce('sale_price', 'price')
).order_by('-current_price')