Reputation: 33
I'm trying to implement a coaching system and I'm a little lost about serialization in django.I have a many to many through model to control the appointments and I want to get all data about the coach/coachee involved in the relationship.
class Appointment(models.Model):
"""docstring for Appointment"""
coach = models.ForeignKey(User, related_name='coaches', on_delete=models.CASCADE)
coachee = models.ForeignKey(User, related_name='coachees', on_delete=models.CASCADE)
schedule_date = models.DateField(auto_now=False, auto_now_add=True, blank=True)
due_date = models.DateField()
summary = models.TextField(max_length=200)
Using the following serializer I can get the primary keys involved but I'd really like to get the coach and coachee details in one request.
#return appointment data
class AppointmentSerializer(serializers.HyperlinkedModelSerializer):
"""docstring for AppointmentSerializer"""
class Meta:
model = Appointment
fields = ('id', 'schedule_date', 'due_date', 'coach', 'coachee', 'summary', 'condition')
Upvotes: 2
Views: 412
Reputation: 8897
There are several ways to do it. The common one is create serializer for user and use it instead of defaults fields:
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ...
class AppointmentSerializer(serializers.ModelSerializer):
coach = UserSerializer()
coachee = UserSerializer()
class Meta:
model = Appointment
fields = ('id', 'schedule_date', 'due_date', 'coach', 'coachee', 'summary', 'condition')
But there will be a problem if you want to use AppointmentSerializer
for creating an instance. You will not be able to pass an id's of users to that fields. In that case you could use default fields and override to_representation
method.
class AppointmentSerializer(serializers.ModelSerializer):
class Meta:
model = Appointment
fields = ('id', 'schedule_date', 'due_date', 'coach', 'coachee', 'summary', 'condition')
def to_representation(self, instance):
representation = super(AppointmentSerializer, self).to_representation(instance)
representation['coach'] = UserSerializer(instance.coach).data
representation['coachee'] = UserSerializer(instance.coachee).data
return representation
Upvotes: 1
Reputation: 29967
Try setting the depth
option on the Meta
class.
class AppointmentSerializer(serializers.HyperlinkedModelSerializer):
"""docstring for AppointmentSerializer"""
class Meta:
model = Appointment
fields = ('id', 'schedule_date', 'due_date', 'coach', 'coachee', 'summary', 'condition')
depth = 1
This will generate nested representations.
Alternatively, you can explicitly specify serializers if you need more control.
class AppointmentSerializer(serializers.HyperlinkedModelSerializer):
coach = CoachSerializer()
coachee = CoacheeSerializer()
class Meta:
model = Appointment
fields = ('id', 'schedule_date', 'due_date', 'coach', 'coachee', 'summary', 'condition')
You can also add single fields from your related models:
class AppointmentSerializer(serializers.HyperlinkedModelSerializer):
"""docstring for AppointmentSerializer"""
coach_name = serializers.CharField(source='coach.name')
class Meta:
model = Appointment
fields = ('id', 'schedule_date', 'due_date', 'coach', 'coachee', 'summary', 'condition')
Upvotes: 1