0

I'm using django-rest-framework and python-social-auth in my Django project.

Here is the serializer class of UserSocialAuth model in my project

class SocialAuthSerializer(serializers.HyperlinkedModelSerializer):
    id = serializers.CharField()

    class Meta:
        model = UserSocialAuth
        fields = ('id', 'provider')

Then I want to an additional field UserSocialAuth.extra_data['login'] to above Serializer, the traditional way should be

class UserSocialAuth(AbstractUserSocialAuth):
    def login:
        return self.extra_data['login']

class SocialAuthSerializer(serializers.HyperlinkedModelSerializer):
    login = serializers.CharField(source='login')
     ...

        fields = ('id', 'provider', 'login')

The problem is that UserSocialAuth is belong to python-social-auth, I have to change the code of python-social-auth app directly to add def login:, so how can I add the additional field to the existing model UserSocialAuth without touching the code of python-social-auth.

Yuwen Yan
  • 4,777
  • 10
  • 33
  • 63
  • If I've understand you correctly, you want to add functionality to an existing class and its serializer. Why can you not write your own class `CustomUserSocialAuth(UserSocialAuth)` and implement the login method there? You could then also write a `CustomSocialAuthSerializer(SocialAuthSerializer)` that inherits the `fields` from the parent and uses the model `CustomUserSocialAuth` and add `login` to its fields accordingly. – dotcs Sep 08 '15 at 11:36
  • But the `UserSocialAuth ` is used in `python-social-auth`, can I use the Serializer of subclass `CustomUserSocialAuth ` to serialise the base class `UserSocialAuth` ? – Yuwen Yan Sep 08 '15 at 12:31
  • I see. In principle you can change the `UserSocialAuth` inside `python-social-auth` then. This is called Monkey-Patching, see here: http://stackoverflow.com/questions/19545982/monkey-patching-a-class-in-another-module-in-python But I would not suggest to do so. If you think the module that you use is doing wrong because it couples the serializer too tightly to the model, you should consider discussing that with the author of the module instead of monkey patching it. – dotcs Sep 08 '15 at 13:27
  • I just find one way to do it without touching the raw class, thank you all the same – Yuwen Yan Sep 09 '15 at 00:43

1 Answers1

0

I just find that I can use SerializerMethodField here, no need to change the raw class UserSocialAuth, just add one more field to the serializer like this:

class SocialAuthSerializer(serializers.HyperlinkedModelSerializer):
    login = serializers.SerializerMethodField()

    def get_login(self, obj):
        return obj.extra_data['login']
Yuwen Yan
  • 4,777
  • 10
  • 33
  • 63