切片后对Django QuerySet进行排序

Eli*_*ICA 1 python sql django orm

Django文档说:

...即使切片未评估的QuerySet返回另一个未评估的QuerySet,也不允许进一步修改它(例如,添加更多过滤器或修改排序),因为这不能很好地转换为SQL,也不会有明确的含义.

从这里我认为这意味着做这样的事情:

q1 = Pizza.objects.all()[0:5]
q2 = q1.order_by(...)
Run Code Online (Sandbox Code Playgroud)

不被允许.我有两个问题:

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

Bur*_*ing 7

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

这是您的查询集:

q1 = Pizza.objects.all()[0:5]
q2 = q1.order_by(...)
Run Code Online (Sandbox Code Playgroud)

相应的SQL语法:

SELECT * FROM Pizza limit 5 order by your_column
Run Code Online (Sandbox Code Playgroud)

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

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

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

它会让你期待.


我建议你order by之前使用slice如下:

q1 = Pizza.objects.all().order_by(...)[0:5]
Run Code Online (Sandbox Code Playgroud)