Search code examples
djangodjango-rest-frameworkdjango-querysetdjango-serializer

Queryset working in regular django but getting KeyError when applying the queryset to a DRF Serializer?


I got the following queryset:

queryset = Expense.objects
.annotate(month=TruncMonth('expense_date'))
.values('month')
.annotate(total_cost=Sum('cost'))
.values('month', 'total_cost')
.order_by("month")

Which essentially sums all expense costs and groups them by month. If I just print out the queryset it works fine:

<QuerySet [{'month': datetime.date(2020, 9, 1), 'total_cost': Decimal('1029772.00')}]>

However, if I try to serializer it:

serializer = ExpenseSerializer(queryset, many=True)

I get

Got KeyError when attempting to get a value for field `cost` on serializer `ExpenseSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'cost'."

serializer.py:

class ExpenseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Expense
        exclude = ("receipt", )

Whats the fuss?


Solution

  • Your ExpenseSerializer is constructed to serialize Expense objects, or dictionaries that contain all the necessary fields your ExpenseSerializer needs.

    Your queryset however only passes two values: month and total_cost. You thus should not wrap it through an ExpenseSerializer, but for example a custom one like:

    class ExpenseSummarySerializer(serializers.Serializer):
        month = serializers.DateField()
        total_cost = serializers.DecimalField(max_digits=9, decimal_places=2)