user1314147
user1314147

Reputation: 362

Return one-to-one model information with model in Django

I have 2 pretty basic Django models: User and UserProfile. I am using the REST framework and would like to include profile information when retrieving all users. I have searched the internet but was not able to find the answer. This is what I am currently trying: User.objects.all().prefetch_related('userprofile')

What I am trying to return is something like:

[
  {'email': '[email protected]',
   'first_name': 'Test', 
   'last_name': 'McTester'},
  {'email': '[email protected]',
   'first_name': 'Mary',
   'last_name': 'McPherson'}
]

where first and last name are profile attributes. I have been able to do something similar using Flask and GraphQL but was wondering if this is possible with REST in Django.

Upvotes: 3

Views: 287

Answers (2)

ruddra
ruddra

Reputation: 51988

Well, what prefetch_related does is load the data from UserProfile model beforehand based on relationship between User model and UserProfile model, so when you call user.userprofile it does not hit database again. But it does not return the value when you call user. So in your model serializer, you can add these two fields with source pointing to UserProfile's first_name and last_name. For example:

class UserSerializer(serializer.ModelSerializer):
     first_name = serializer.CharField(source='userprofile.first_name', read_only=True)
     last_name = serializer.CharField(source='userprofile.last_name', read_only=True)

     class Meta:
         model = User
         fields = ['email', 'first_name', 'last_name']

Upvotes: 4

Alejandroid
Alejandroid

Reputation: 199

You could define two serializers:

class UserProfileSerializer(serializer.ModelSerializer):
    class Meta:
        model = UserProfile
        fields = ['first_name', 'last_name']
class UserSerializer(serializer.ModelSerializer):
    user_profile = UserProfileSerializer(many=False)

    def to_representation(self, instance):
        data = super(UserSerializer, self).to_representation(instance)
        user_profile_data = data.pop('user_profile')
        for key, val in user_profile_data.items():
            data.update({key: val})
        return data

    class Meta:
        model = User
        fields = ['email']

Hope it helps you :)

Upvotes: 0

Related Questions