2

Consider a table Person:

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

We want to sort the rows by wealth, descending, i.e. to get (Abby, Carl, Ben, Diane), but Django's order_by function sorts them by Null first:

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

gives (Ben, Diane, Abby, Carl), i.e. it first lists the Null values then sorts by wealth.


I tried redefining the get_queryset method:

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)

This does return the desired behavior, (Abby, Carl, Ben, Diane) but messes up the detail view, and gives the get() returned multiple values error.


Is there a way to get the desired behavior, by customizing the ordering functionality, or modifying get_queryset only for the list view?

4

2 回答 2

5

从更新日志django 1.11

在 Expression.asc() 和 desc() 中添加了 nulls_first 和 nulls_last 参数以控制 null 值的顺序。


因此,如果您使用的是django>=1.11,您可以Expression.desc()按如下方式对字段进行排序,

from django.db.models import F

queryset = Person.objects.all().order_by(F('wealth').desc(nulls_last=True))
于 2018-03-02T04:51:22.403 回答
1

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

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

于 2019-05-16T12:41:13.540 回答