我是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。
我能用它实现任何功能吗?
答案 0 :(得分:7)
如果确实想要在数据库级别执行所有操作,您可以按计算值排序。这应该有效:
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。
答案 1 :(得分:4)
以下可能有效,它不是最好的代码实现,但对于您的特殊情况,我认为这是使用queryset直接执行它的简单方法,否则您可以考虑在Python中实现它(已排序或其他内置函数)
qs = Product.objects.exclude(price=0).order_by('-price') | Product.objects.filter(price=0)
答案 2 :(得分:1)
您想要实现的是此SQL查询:
SELECT * FROM product ORDER BY price = 0, price;
使用Django的ORM,使用extra()过滤器修饰符:
Product.objects.extra(select={"custom":"price = 0"}, order_by=["custom","price"]).all()
答案 3 :(得分:1)
Conditional Expressions允许您在过滤器,注释,聚合和更新中使用if ... elif ... else逻辑。条件表达式为表的每一行计算一系列条件,并返回匹配的结果表达式。
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的回答和评论修复bug。