可空列的 Django REST ViewSet 排序

Django REST ViewSet ordering for Null-able columns

考虑一个 table 人:

| name | wealth |
|------| ------ |
|Abby  | 12     |
|Ben   | Null   |
|Carl  | 5      |
|Diane | Null   |

我们想按财富降序对行进行排序,即得到(Abby, Carl, Ben, Diane),但是Django的order_by函数首先按Null对它们进行排序:

class PersonViewSet(serializers.ModelViewSet):
        serializer_class = PersonSerializer
        queryset = Person.objects.all().order_by('-wealth)

给出 (Ben, Diane, Abby, Carl),即它首先列出 Null 值,然后按财富排序。


我尝试重新定义 get_queryset 方法:

class PersonViewSet(serializers.ModelViewSet):
    serializer_class = PersonSerializer

    def get_queryset():
        invalid_entries = Person.objects.filter(wealth=None)
        valid_entries = Person.objects.all().difference(invalid_entries).order_by('-wealth')
        return valid_entries.union(invalid_entries)

这确实 return 了预期的行为,(Abby, Carl, Ben, Diane) 但弄乱了详细视图,并给出了 get() returned multiple values 错误。


有没有办法通过自定义排序功能或修改 get_queryset 列表视图来获得所需的行为?

来自django 1.11changelog

Added the nulls_first and nulls_last parameters to Expression.asc() and desc() to control the ordering of null values.


所以,如果您使用 django>=1.11,您可以使用 Expression.desc() 方法对您的字段进行排序,

from django.db.models import F

queryset = Person.objects.all().order_by(F('wealth').desc(nulls_last=True))

除了回答。 您还可以在视图中定义 Options.ordering 属性 class:

class PersonViewSet(serializers.ModelViewSet):
    serializer_class = PersonSerializer
    ordering = [F('wealth').desc(nulls_last=True)]