Reputation: 130
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!!
Upvotes: 4
Views: 6436
Reputation: 314
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()
...
Upvotes: 2
Reputation: 130
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.
Upvotes: 7