切片后对Django QuerySet进行排序

时间:2015-10-06 00:19:38

标签: python sql django orm

Django docs说:

  

...即使切片未评估的QuerySet返回另一个未评估的QuerySet,也不允许进一步修改它(例如,添加更多过滤器或修改排序),因为这不能很好地转换为SQL并且它不会很清楚意思是。

从这一点来看,我认为这意味着做这样的事情:

q1 = Pizza.objects.all()[0:5]
q2 = q1.order_by(...)

是不允许的。我有两个问题:

  • 为什么文档说这个?我可以理解,也许它并没有很好地转化为SQL,但对我而言,“明确的含义”是你得到前5个披萨对象,然后你按照任何标准订购它们。
  • 如果你这样做会怎么样?我已经做了一段时间,代码是正确的(但很慢)。它是否实际反向执行 - 按顺序排列所有Pizza个对象,然后获取前5个?

1 个答案:

答案 0 :(得分:6)

编写ORM代码时,它实际上与SQL语法相对应。特别是,ORM产生错误的SQL语法。当然它会导致错误。

这是您的查询集:

q1 = Pizza.objects.all()[0:5]
q2 = q1.order_by(...)

相应的SQL语法:

SELECT * FROM Pizza limit 5 order by your_column

所以这是一个明显的错误。

代码如何更正ORM?根据您的要求,我建议您跟进:

q1 = Pizza.objects.all()[0:5]
q2 = q1.sorted(q1, key=lambda x: x.your_column)

它会让你期待。

我建议您在order by之前使用slice作为以下内容:

q1 = Pizza.objects.all().order_by(...)[0:5]