I have 2 models:
from django.db import models
STATUSES = (
('f', 'Finished'),
)
class Battery(models.Model):
energy = models.CharField(max_length=10)
current = models.CharField(max_length=10)
class Charger(models.Model):
status = models.CharField(max_length=1, choices=STATUSES)
And I want to create serializer that will serialize this 2 models together. My serializers.py:
from rest_framework import serializers
from .models import Battery, Charger
class BatterySerializer(serializers.ModelSerializer):
class Meta:
model = Battery
class ChargerSerializer(serializers.ModelSerializer):
status = serializers.SerializerMethodField()
class Meta:
model = Charger
def get_status(self, obj):
return obj.get_status_display()
class DeviceSerializer(serializers.Serializer):
battery = BatterySerializer()
charger = ChargerSerializer()
some_field = serializers.CharField()
Because Charger model has choices in status field I add SerializerMethodField for displaying full status. Then I create a view like this:
class DeviceView(APIView):
def get(self, request, format=None):
battery = Battery.objects.get(id=1)
charger = Charger.objects.get(id=1)
battery_serializer = BatterySerializer(battery)
charger_serializer = ChargerSerializer(charger)
serializer = DeviceSerializer(data={
'battery': battery_serializer.data,
'charger': charger_serializer.data,
'some_field': 'some_text'
})
if serializer.is_valid():
return Response(serializer.validated_data)
else:
return Response(status = 500)
But when I call this view it returns json with empty charger field:
{
"battery": {
"energy": "12",
"current": "34"
},
"charger": {},
"some_field": "some_text"
}
But when I create a view that serialize only Charger model:
class ChargerView(APIView):
def get(self, request, format=None):
charger = Charger.objects.get(id=1)
charger_serializer = ChargerSerializer(charger)
return Response(charger_serializer.data)
It works and it returns this json:
{
"id": 1,
"status": "Finished"
}
Why this happens? Where did I make a mistake?
BatterySerializerandChargerSerializermethods independently in your view and return them? Since that is what yourDeviceSerializeris doing.{ 'battery': battery.__dict__, 'charger': charger.__dict__, 'some_field': 'some_text' }? not sure if this is the right way though.serializer.is_valid()? Can you directly returnResponse(serializer.data)and see what you get?Response(serializer.data)It raise AssertionError:When a serializer is passed a data keyword argument you must call .is_valid() before attempting to access the serialized .data representation. You should either call .is_valid() first, or access .initial_data instead.