How to sort values of serializer custom field in DRF

泪湿孤枕 提交于 2020-06-26 07:43:45

问题


I have created a custom field in the client serializer. The value of this field is calculated by a complex serializer method.

class ClientsStatsSerializer(serializers.ModelSerializer):
    """
    Serializer shows total_spend for 2019 by client.
    """
    refs_count = serializers.SerializerMethodField()
    total_spend_2019 = serializers.SerializerMethodField()

    class Meta:
        model = Company
        ordering = ('total_spend_2019',)
        fields = [
            'id',
            'legal_name',
            'refs_count',
            'total_spend_2019',
        ]
        def get_total_spend_2019(self, obj):
            ...

I would like to get the output sorted by the value of total_spend_2019. It looks like I cannot do it here with a simple ordering = ('total_spend_2019',) I cannot do it either in the model, neither in the view.

EDIT: It would be great to have a generic solution that would work with any SerializerMethodField.

Current view is as such:

class ClientsStatsViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = request.user.company.clients.all()

        client_id = self.request.query_params.get('client_id', None)
        if client_id is not None:
            queryset = queryset.filter(pk=client_id)

        serializer = ClientsStatsSerializer(queryset, many=True)
        return Response(serializer.data)

Any idea how to solve this?

Thank you very much!!


回答1:


All right, I managed to solve it with the following:

class ClientsStatsViewSet(viewsets.ViewSet):
    def list(self, request):
        queryset = request.user.company.clients.all()

        client_id = self.request.query_params.get('client_id', None)
        if client_id is not None:
            queryset = queryset.filter(pk=client_id)

        serializer = ClientsStatsSerializer(queryset, many=True)
        serializer_data = sorted(
            serializer.data, key=lambda k: k['total_spend_2019'], reverse=True)
        return Response(serializer_data)

I don't know if it is the most performant way to do this, but it works.




回答2:


Also you can try create your custom model manager. This is popular decision for ordering data:

models.py

class CustomManager(models.Manager):
    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset.filter(...).order_by(...)


class Company(models.Model):
    ...

   objects = models.Manager
   custom_manager = CustomManager()


views.py

class CompanyViewSet(viewsets.ViewSet):
    ...
    queryset = Company.custom_manager.all()
    ...



来源:https://stackoverflow.com/questions/56942068/how-to-sort-values-of-serializer-custom-field-in-drf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!