0

对于项目库,用户可以手动对一些项目进行排序以始终使它们首先出现。

为此,模型有一个“排序”而不是 null PositiveIntegerField(默认为 0)。排序字段大于零的项目是手动排序的,并且必须出现在排序值为 0 的未排序项目之前。

可以使用的 SQL 查询可能是这样的:

(select photo, sort, 0 as priority from photos where sort > 0)
union all
(select photo, sort, 1 as priority from photos where sort = 0)
order by priority, sort

结果看起来像:

+---------+------+----------+
| photo   | sort | priority |
+---------+------+----------+
| photo-a | 1    | 0        |
| photo-b | 2    | 0        |
| photo-c | 0    | 1        |
| photo-d | 0    | 1        |
| photo-e | 0    | 1        |
| ...                       |

但我不知道应该如何使用 Django Queryset 正确完成它?

我可以合并两个不同的list(chain(q1, q2))查询集,但是查询被执行,这对于大型集合来说效率低下,特别是如果我的查询集应该被传递给 django.core.paginator 通常会应用 LIMIT OFFSET 子句进行分页。当然,我可以对每个查询应用切片q1q2但这有点难看,因为它与分页器的功能重叠。

也许我试图以错误的方式做到这一点。或者也许应该用extra()方法来完成?

4

2 回答 2

1

对查询集进行联合/合并不是解决方案。一个更简单的解决方案是在 order 语句中使用比较。stackeoverflow 上的一个答案向我指出了这个巧妙的解决方案。

select * from photos order by sort=0, sort

0=0 被评估为 True 等于 1,1=0 是 False 等于 0 等等。明白了吗?

翻译成 Django 查询集:

Photos.objects.extra(select={'sortiszero': 'sort = 0'}, order_by=['sortiszero', 'sort'])

结果:

+---------+------+
| photo   | sort |
+---------+------+
| photo-a | 1    |
| photo-b | 2    |
| photo-c | 0    |
| photo-d | 0    |
| photo-e | 0    |
| ...            |

瞧!

于 2013-01-15T09:52:33.100 回答
0

你应该提供更多细节。

如果你想合并这两组,你可以简单地添加列表:

list1 = SomeModel.objects.filter(sort != 0).order_by('column_name_1','column_name_2')
list2 = SomeModel.objects.filter(sort = 0).order_by('priority','foo')
return list = list1 + list2

或者如果你想使用 extra() 方法,这里是一个例子:

list = SomeModel.objects.fooMethod().extra(order_by=[foo,])
于 2013-01-14T17:02:36.183 回答