kubaSpolsky
kubaSpolsky

Reputation: 357

how to format field name and round the value

I got a query "top 3 employees in terms of total invoice value" based on the following related tables:

enter image description here

    
    [{
        "customerid__supportrepid__id": 3,
        "sells": 833.0400000000013
    },
    ...]

I would like the first filed to be: "employee_id" and a sells field value

    class CustomerViewSet(viewsets.ReadOnlyModelViewSet):

    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer

    @action(detail=False, methods=['get'])
    def top_three_employees(self, request):
        total_sells_by_employees = Invoice.objects \
                                                .select_related('customerid') \
                                                .select_related('customerid__supportrepid') \
                                                .values('customerid__supportrepid__id') \
                                                .annotate(sells=Sum('total')) \
                                                .order_by('-sells')

        return Response(total_sells_by_employees)

Upvotes: 0

Views: 142

Answers (2)

Mohsin Maqsood
Mohsin Maqsood

Reputation: 190

You can rename fields in a Django queryset using the values() method [django-doc]:
MyModel.objects.values(renamed_field_name=F('original_field_name'))
This will thus construct a queryset where the original_field_name is renamed to renamed_field_name.
In a serializer, you can then rename the field with:
class MySerializer(serializers.Serializer):
    renamed_field_name = serializers.CharField()
So by defining a field with the target name, and omitting a source, it will automatically take the field with the same name in the object that is serialized.

Upvotes: 1

Mohsin Maqsood
Mohsin Maqsood

Reputation: 190

You can use .annotate() to create an aliased, transformed field, and then serialize that field:
from django.db.models.functions import Round

MyModel.objects.annotate(
    rounded_field=Round('field_name', 2)
).values('rounded_field')
This will add a rounded_field to the queryset that is the field_name rounded to two digits.
You can then rename this in the serializer fields mapping, with:
class MyModelSerializer(serializers.ModelSerializer):
    rounded_field = serializers.SerializerMethodField()

    class Meta:
        fields = ('rounded_field',)
    
    def get_rounded_field(self, instance):
        return instance.rounded_field
This will thus serialize the rounded_field as rounded_field, under the name you specified in the fields of the serializer.

Upvotes: 0

Related Questions