简体   繁体   中英

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@example.com',
   'first_name': 'Test', 
   'last_name': 'McTester'},
  {'email': 'user2@example.com',
   '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.

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']

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:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM