在忽略值的同时排序查询集

Ordering a queryset while ignoring a value

我有一个字段hotrank,它保存了热门音乐(1,2,3,4...10)
但如果音乐没有进入前 10 名,我将节省 0。
我还有另一个名为 releaseday 的字段,它保存了音乐的发行日期

现在我想查询:

 Music.objects.filter(releaseday__lte=today).order_by('hotrank','-releaseday') 

但是这里有个问题,hotrank的order_by是从0开始的,但是0不是top music
怎么才能让order_by从hotrank=1开始呢?有什么方法吗?

我认为您可以从查询结果中得到 hotrank=0 的结果,如下所示:

Music.objects.filter(releaseday__lte=today).exclude(hotrank=0).order_by(
                     '-hotrank','-releaseday') 

如果你想在排序的结果之后添加 hotrank=0 的结果,你可以这样做:

released_music = Music.objects.filter(releaseday__lte=today).order_by('-hotrank',
                                                                      '-releaseday')
result = released_music.exclude(hotrank=0) | released_music.filter(hotrank=0) 

我认为没有办法通过 Django 查询来实现这一点。我也不鼓励您使用任何特定于数据库的查询。您可以从数据库中提取所有对象并按照您想要的方式对它们进行排序 Python:

music_list = Music.objects.filter(releaseday__lte=today).all()
sorted_music = sorted(music_list, key=lambda x: x.hotrank if x.hotrank > 0 else 11)

将查询集的 extra() 方法与 SQL CASE 表达式一起使用:

Music.objects.filter(releaseday__lte=today) \
             .extra({'vrank': 'CASE WHEN hotrank=0 THEN 11 ELSE hotrank END'}) \
             .order_by('vrank','-releaseday')