按升序排列 Django 查询集,但末尾为 0 值项
Order a Django queryset in ascending order but with 0-valued items at the end
我是 python、django 的新手。我想要做的是我有一个定义为产品的模型,它有两列:名称和价格。
name price
pen 20
paper 30
eraser 0
我正在尝试使用以下代码对它们进行排序:
Product.objects.all().order_by('-price')
这会将值排序为 0,20,30
。
型号编码为
class Product(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
price = models.IntegerField('Price', blank=True, null=True)
我想要实现的是将其排序为 20,30,0
,最后附加 0。
有什么功能可以实现吗?
以下可能可行,它不是最好的实现代码,但对于您的特殊情况,我认为这是直接使用查询集执行此操作的简单方法,否则您可以考虑在 Python(排序或其他内置函数)
qs = Product.objects.exclude(price=0).order_by('-price') | Product.objects.filter(price=0)
如果您真的想在数据库级别完成所有操作,您可以按计算值排序。这应该有效:
Product.objects.all().order_by(\
Case(When(price=0, then=Value(MAX_INT)), default=F('price')))
其中 MAX_INT=2147483647
是 32 位有符号整数的值,即 safe on all Django-supported DBs。
你想要实现的是这个SQL查询:
SELECT * FROM product ORDER BY price = 0, price;
使用 Django 的 ORM,使用 extra() 过滤器修饰符:
Product.objects.extra(select={"custom":"price = 0"}, order_by=["custom","price"]).all()
Conditional Expressions let you use if ... elif ... else logic within filters, annotations, aggregations, and updates. A conditional expression evaluates a series of conditions for each row of a table and returns the matching result expression.
from django.db.models import IntegerField, Case, Value, When
MAX_INT = 2147483647
Product.objects.annotate(
my_price=Case(
When(price=0, then=Value(MAX_INT)),
default='price',
output_field=IntegerField(),
)
).order_by('my_price')
已编辑:根据@ivan 的回答和评论修复错误。
我是 python、django 的新手。我想要做的是我有一个定义为产品的模型,它有两列:名称和价格。
name price
pen 20
paper 30
eraser 0
我正在尝试使用以下代码对它们进行排序:
Product.objects.all().order_by('-price')
这会将值排序为 0,20,30
。
型号编码为
class Product(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
price = models.IntegerField('Price', blank=True, null=True)
我想要实现的是将其排序为 20,30,0
,最后附加 0。
有什么功能可以实现吗?
以下可能可行,它不是最好的实现代码,但对于您的特殊情况,我认为这是直接使用查询集执行此操作的简单方法,否则您可以考虑在 Python(排序或其他内置函数)
qs = Product.objects.exclude(price=0).order_by('-price') | Product.objects.filter(price=0)
如果您真的想在数据库级别完成所有操作,您可以按计算值排序。这应该有效:
Product.objects.all().order_by(\
Case(When(price=0, then=Value(MAX_INT)), default=F('price')))
其中 MAX_INT=2147483647
是 32 位有符号整数的值,即 safe on all Django-supported DBs。
你想要实现的是这个SQL查询:
SELECT * FROM product ORDER BY price = 0, price;
使用 Django 的 ORM,使用 extra() 过滤器修饰符:
Product.objects.extra(select={"custom":"price = 0"}, order_by=["custom","price"]).all()
Conditional Expressions let you use if ... elif ... else logic within filters, annotations, aggregations, and updates. A conditional expression evaluates a series of conditions for each row of a table and returns the matching result expression.
from django.db.models import IntegerField, Case, Value, When
MAX_INT = 2147483647
Product.objects.annotate(
my_price=Case(
When(price=0, then=Value(MAX_INT)),
default='price',
output_field=IntegerField(),
)
).order_by('my_price')
已编辑:根据@ivan 的回答和评论修复错误。