How to get a json
with relate model but without nested in Django rest framework?
Code :
Models, Session
and Athlete
, Athlete
models has foreign key relationship with Session
class Session(models.Model):
Id = models.AutoField(primary_key=True)
SessionNo = models.SmallIntegerField()
WinTeam = models.SmallIntegerField(null=True)
class Athlete(models.Model):
Id = models.AutoField(primary_key=True)
Name = models.CharField(max_length=6)
Age = models.SmallIntegerField()
Session = models.ForeignKey(Session, on_delete=models.CASCADE, related_name='athletes')
Status = models.SmallIntegerField()
Serializers
class SessionSerializer(serializers.ModelSerializer):
class Meta:
model = Session
fields = '__all__'
class AthleteSerializer(serializers.ModelSerializer):
Session = SessionSerializer(read_only=True)
class Meta:
model = Athlete
fields = ('Age', 'Status', 'Session')
And views:
def all_athletes(request):
"""
Get all athletes list
"""
queryset = Athlete.objects.all().select_related()
serializer = AthleteSerializer(instance=queryset, many=True)
return Response(serializer.data)
And the API result is :
[
{
"Age": 38,
"Status": 1,
"Session": {
"Id": 13,
"SessionNo": 1,
"WinTeam": null
}
},
{
"Age": 26,
"Status": 1,
"Session": {
"Id": 13,
"SessionNo": 1,
"WinTeam": null
}
},
{
"Age": 35,
"Status": 2,
"Session": {
"Id": 13,
"SessionNo": 1,
"WinTeam": null
}
}
]
It works to get relate model, but I want relate models show without nested, how to do to fit my expectation ?
I expect the API result:
[
{
"Age": 38,
"Status": 1,
"Id": 13,
"SessionNo": 1,
"WinTeam": null
},
{
"Age": 26,
"Status": 1,
"Id": 13,
"SessionNo": 1,
"WinTeam": null
},
{
"Age": 35,
"Status": 2,
"Id": 13,
"SessionNo": 1,
"WinTeam": null
}
]
CodePudding user response:
You could try SerializerMethodFields....
class AthleteSerializer(serializers.ModelSerializer):
Id = serializers.SerialierMethodField(read_only=True)
SessionNo = serializers.SerialierMethodField(read_only=True)
WinTeam = serializers.SerialierMethodField(read_only=True)
class Meta:
model = Athlete
fields = ('Age', 'Status', 'Id', 'SessionNo', 'WinTeam')
def get_Id(self, obj):
return obj.Session.id
def get_SessionNo(self, obj):
return obj.Session.SessionNo
def get_WinTeam(self, obj):
return obj.Session.WinTeam
And then remember to prefetch the Session relationship(s) in your view's queryset or else it will hit the database multiple times for those multiple fields
CodePudding user response:
You can override to_representation()
in AthleteSerializer
as well. With that you do not need SerialierMethodField
.
def to_representation(self, value):
ref = super().to_representation(value)
session = ref.pop("Session")
ref.update(**session)
return ref