我需要在Django ORM中实现以下目标:
(SELECT * FROM `stats` WHERE MODE = 1 ORDER BY DATE DESC LIMIT 2)
UNION
(SELECT * FROM `stats` WHERE MODE = 2 ORDER BY DATE DESC LIMIT 2)
UNION
(SELECT * FROM `stats` WHERE MODE = 3 ORDER BY DATE DESC LIMIT 2)
UNION
(SELECT * FROM `stats` WHERE MODE = 6 ORDER BY DATE DESC LIMIT 2)
UNION
(SELECT * FROM `stats` WHERE MODE = 5 AND is_completed != 3 ORDER BY DATE DESC)
# mode 5 can return more than 100 records so NO LIMIT here
我为此写的:
query_run_now_job_ids = Stats.objects.filter(mode=5).exclude(is_completed=3).order_by('-date')
list_of_active_job_ids = Stats.objects.filter(mode=1).order_by('-date')[:2].union(
Stats.objects.filter(mode=2).order_by('-date')[:2],
Stats.objects.filter(mode=3).order_by('-date')[:2],
Stats.objects.filter(mode=6).order_by('-date')[:2],
query_run_now_job_ids)
但是以某种方式返回的 list_of_active_job_ids 是无序的,即list_of_active_job_ids.ordered
返回 False ,由于此查询传递给 Paginator 类时,给出:
UnorderedObjectListWarning:
Pagination may yield inconsistent results with an unordered object_list
我已经在models.py中的Meta类中设置了排序
class Meta:
ordering = ['-date']
没有分页器查询可以很好地工作并且可以加载页面,但是使用分页器时,视图永远不会加载。
在不使用联合链的情况下,还有其他更好的替代方案吗?
因此,我尝试了上述MySQL查询的另一种替代方法,但在此查询中,我陷入了另一个问题,无法为 mode = 5 编写条件:
SELECT
MODE ,
SUBSTRING_INDEX(GROUP_CONCAT( `job_id` SEPARATOR ',' ),',',2) AS job_id_list,
SUBSTRING_INDEX(GROUP_CONCAT( `total_calculations` SEPARATOR ',' ),',',2) AS total_calculations
FROM `stats`
ORDER BY DATE DESC
即使我能够编写此查询,它也将导致我进入另一个具有挑战性的情况,即将该查询转换为Django ORM。
那么,即使我在Class Meta中进行了设置,为什么我的查询也没有排序。
如果不是此查询,是否还有更好的替代方法实现?
我们将不胜感激!
我正在使用Python 2.7和Django 1.11。
答案 0 :(得分:0)
虽然可以查询子查询,但不能查询结果联合数据。您需要明确定义顺序。
from django.db import models
def make_query(mode, index):
return (
Stats.objects.filter(mode=mode).
annotate(_sort=models.Value(index, models.IntegerField())).
order_by('-date')
)
list_of_active_job_ids = make_query(1, 1)[:2].union(
make_query(2, 2)[:2],
make_query(3, 3)[:2],
make_query(6, 4)[:2],
make_query(5, 5).exclude(is_completed=3)
).order_by('_sort', '-date')
我要做的就是添加一个新的文字值字段_sort
,该字段的每个子查询都有不同的值,然后在最终查询中对其进行排序。其余代码只是为了减少重复。如果不是那个mode=6
子查询,它甚至会更干净。