Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return nested serializer in serializer method field

I have a method field called followers. I get the list of followers in a SerializerMethodField :

followers = serializers.SerializerMethodField()

I want to format the result with a specific serializer called BaseUserSmallSerializer. How should I implement the method get_followers to achieve that ?

like image 478
Ambroise Collon Avatar asked Nov 26 '15 18:11

Ambroise Collon


2 Answers

Try this;

followers = BaseUserSmallSerializer(source='get_followers', many=True)

OR

You can use serializer inside methodfield;

def get_followers(self, obj):
   followers_queryset = #get queryset of followers
   return  BaseUserSmallSerializer(followers_queryset, many=True).data
like image 167
Geo Jacob Avatar answered Oct 18 '22 22:10

Geo Jacob


If you prefer a more generic solution:

SerializerMethodNestedSerializer which works same as serializers.SerializerMethodField but wraps the result with the passed serializer and returns a dict

class SerializerMethodNestedSerializer(serializers.SerializerMethodField):
    """Returns nested serializer in serializer method field"""

    def __init__(self, kls, kls_kwargs=None, **kwargs):
        self.kls = kls
        self.kls_kwargs = kls_kwargs or {}
        super(SerializerMethodNestedSerializer, self).__init__(**kwargs)

    def to_representation(self, value):
        repr_value = super(SerializerMethodNestedSerializer, self).to_representation(value)
        if repr_value is not None:
            return self.kls(repr_value, **self.kls_kwargs).data

Usage

class SomeSerializer(serializers.ModelSerializer):
    payment_method = SerializerMethodNestedSerializer(kls=PaymentCardSerializer)

    def get_payment_method(self, obj):
        return PaymentCard.objects.filter(user=obj.user, active=True).first()

    class Meta:
        model = Profile
        fields = ("payment_method",)
class PaymentCardSerializer(serializers.ModelSerializer):

    class Meta:
        fields = ('date_created', 'provider', 'external_id',)
        model = PaymentCard

The expected output of SerializerMethodNestedSerializer(kls=PaymentCardSerializer)

None or {'date_created': '2020-08-31', 'provider': 4, 'external_id': '123'}
like image 1
pymen Avatar answered Oct 18 '22 22:10

pymen