使用Django Rest Framework忽略降序的空值

Shu*_*ham 3 django null django-rest-framework

我将Django用于我的网站,因此决定使用Django Rest Framework来构建我的REST API。对于特定的模型,我想过滤一个文本字段(为此使用SearchFilter),过滤几个分类字段(已定义FilterSet的FilterBackend),并能够基于某些字段对数据进行排序(为此使用OrderingFilter)。

class StatsAPI(generics.ListAPIView):
    model = Stats
    queryset = Stats.objects.all()
    serializer_class = StatsSerializer
    filter_backends = (filters.DjangoFilterBackend, filters.OrderingFilter, filters.SearchFilter)
    filter_class = StatsFilter
    pagination_class = StatsPagination
    ordering_fields = ('__all__')
    search_fields = ('display_name')
Run Code Online (Sandbox Code Playgroud)

我面临的问题是我的订购字段,因为它们也包含null。按升序排序可以正常工作。但是,按降序排序(www.example.com/api/stats/?ordering=-appearance),会将空值推到顶部。

使用降序时如何忽略空值?可以执行排序的字段数大约为20。

Sco*_*ord 10

这是一个略有不同的解决方案-而不是过滤掉空值,而是替换掉filter.OrderingFilter始终确保它们排在最后:

class NullsAlwaysLastOrderingFilter(filters.OrderingFilter):
    """ Use Django 1.11 nulls_last feature to force nulls to bottom in all orderings. """
    def filter_queryset(self, request, queryset, view):
        ordering = self.get_ordering(request, queryset, view)

        if ordering:
            f_ordering = []
            for o in ordering:
                if not o:
                    continue
                if o[0] == '-':
                    f_ordering.append(F(o[1:]).desc(nulls_last=True))
                else:
                    f_ordering.append(F(o).asc(nulls_last=True))

            return queryset.order_by(*f_ordering)

        return queryset
Run Code Online (Sandbox Code Playgroud)


Sur*_*ano 0

假设您的字段名称位于stats此处,排序是否会排除空值,您可以执行以下操作:

Stats.objects.exclude(stats__isnull=True).exclude(stats__exact='')
Run Code Online (Sandbox Code Playgroud)