Django ordena elementos por dos campos, pero los ignora si son cero

Resuelto Ben asked hace 13 años • 2 respuestas

Tengo el siguiente modelo (muy simplificado para los propósitos de esta pregunta):

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)

Para la mayoría de los productos, se completará el precio, pero no el precio_venta. Entonces, puedo ordenar productos por precio así:

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

Sin embargo, algunos productos tendrán un precio de oferta y no puedo encontrar una manera de ordenarlos de manera ordenada para que el precio de oferta se intercale con el precio normal. Si intento ordenar por ambos campos:

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

...luego aparecen juntos todos los productos que no están en oferta, seguidos de todos los que sí, en lugar de intercalar los precios.

¿Esto tiene sentido? ¿Alguien tiene una manera de resolver esto?

¡Gracias!

Ben avatar May 14 '11 17:05 Ben
Aceptado

Si te topas con este requisito y estás usando Django 1.8 y superior, puedes usar django.db.models.functions.Coalesceuna solución ligeramente mejor, entre motores de base de datos:

from django.db.models.functions import Coalesce

Product.objects.annotate(
    current_price=Coalesce('sale_price', 'price')
).order_by('-current_price')
tutuDajuju avatar Sep 29 '2015 15:09 tutuDajuju

Puede usar el método QuerySet extra() para crear un campo adicional en su consulta usando la función COALESCE en SQL, que devuelve el primer valor no NULL que se pasa.

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

Tienes que poner tu order_by en la llamada extra() ya que el campo manual adicional "realmente no existe" en lo que respecta al resto del ORM, pero la sintaxis es la misma que la de los order_by() normales de Django.

Consulte la documentación extra() aquí: http://docs.djangoproject.com/en/1.3/ref/models/querysets/#extra

ojno avatar May 14 '2011 12:05 ojno