Как отсортировать значения настраиваемого поля сериализатора в DRF - PullRequest
2 голосов
/ 08 июля 2019

Я создал настраиваемое поле в клиентском сериализаторе. Значение этого поля рассчитывается методом комплексного сериализатора.

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):
            ...

Я бы хотел отсортировать вывод по значению total_spend_2019. Похоже, я не могу сделать это с помощью простого ordering = ('total_spend_2019',) Я не могу сделать это ни в модели, ни в представлении.

РЕДАКТИРОВАТЬ: Было бы замечательно иметь общее решение, которое будет работать с любым SerializerMethodField.

Текущий вид таков:

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)

Есть идеи, как это решить?

Большое спасибо !!

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Хорошо, мне удалось решить это со следующим:

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)

Я не знаю, является ли это наиболее эффективным способом сделать это, но это работает.

0 голосов
/ 09 июля 2019

Также вы можете попробовать создать свой собственный менеджер моделей. Это популярное решение для заказа данных:

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()
    ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...