Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在django中包含条件order_by?_Python_Django_Sorting_Django 1.10 - Fatal编程技术网

Python 如何在django中包含条件order_by?

Python 如何在django中包含条件order_by?,python,django,sorting,django-1.10,Python,Django,Sorting,Django 1.10,我需要根据布尔字段对查询集的两个部分进行不同的排序。 -bool_val==True的行应排在第一位,并按日期a升序排序。 -bool_val==False的行应排在第二位,并按日期b降序排序 我得到的最接近的是 MyModel.objects.all().annotate( sort_order=Case( When(bool_val=True, then=('date_a')), default='date_b') ).order_by('-

我需要根据布尔字段对查询集的两个部分进行不同的排序。 -bool_val==True的行应排在第一位,并按日期a升序排序。 -bool_val==False的行应排在第二位,并按日期b降序排序

我得到的最接近的是

MyModel.objects.all().annotate(
    sort_order=Case(
        When(bool_val=True, then=('date_a')), 
        default='date_b')
    ).order_by('-bool_val', 'sort_order')
但这是按相同的顺序排列的。如果我需要排序的值是数值,那么我会在注释中将一个集合乘以-1,但它们是日期值,所以这不起作用


我还研究了创建两个单独的查询集并将它们组合起来,但是union()直到1.11才可用,我必须支持1.10,我发现的其他组合查询集的方法要么不保持顺序,要么不会生成查询集(或者两者都有)。(我不清楚union()是否保留顺序,但这是没有意义的,所以我也没有深入研究。)最后必须是django QuerySet对象。

您应该能够使用表达式将日期时间转换为时间戳,这样您就可以对它们进行否定

对于MySQL,这是
UNIX\u TIMESTAMP
函数

MyModel.objects.annotate(
    sort_order=Case(
        When(bool_val=True, then=Func(F('date_a'), function='UNIX_TIMESTAMP')), 
        When(bool_val=False, then=Value(0) - Func(F('date_b'), function='UNIX_TIMESTAMP')), 
    )
).order_by('-bool_val', 'sort_order')
对于PostgreSQL,这是
EXTRACT(从带有时区“”的时间戳中提取历元)


有点麻烦。。。而且可能很慢。我没有测试过这个

这就是最终起作用的原因:

MyModel.objects.annotate(
    sort_order_true=Case(
        When(bool_val=True, then=('date_a')),
        default=None
    ),
    sort_order_false=Case(
        When(bool_val=False, then=('date_b')),
        default=None
    )
).order_by(
    'sort_order_true',
    '-sort_order_false',
)

您可以在日期上使用负号:
.order\u by('bool\u val','-sort\u order')
是的,但您不能有条件地这样做。这是一个好主意,但django试图将
“带时区的时间戳的历元”
解释为字段名时遇到了麻烦。我尝试了几个变体,但最终找到了一个更优雅的解决方案;请参阅我发布的答案。感谢您提出此解决方案。我遇到了与@CharlotteMays相同的问题,最后我使用了这个:
Extract('date\u a','epoch')
代替了
Func(F('date\u a'),function='UNIX\u TIMESTAMP')
MyModel.objects.annotate(
    sort_order_true=Case(
        When(bool_val=True, then=('date_a')),
        default=None
    ),
    sort_order_false=Case(
        When(bool_val=False, then=('date_b')),
        default=None
    )
).order_by(
    'sort_order_true',
    '-sort_order_false',
)