[Fixed]-Django Rest Serializer get data related through Foreign Keys

1👍

You can do this with a ModelSerializer:

Note: I will asumme that 'posts.Post' is model C

class CsSerializer(serializers.ModelSerializer):

    class Meta:
        model = C
        fields = ('name')


class AsSerializer(serializers.ModelSerializer):

    post_id = CsSerializer()

    class Meta:
        model = A
        # exclude = ('field_you_dont_want_1', 'field_you_dont_want_2')
        # fields = ('field_you_want_1', 'field_you_want_2')

Note that in CsSerializer you can return any field you want from model C in this case I’m just returning a name.

If you just need a string, you could use StringRelatedField

class AsSerializer(serializers.ModelSerializer):
    post_id = serializers.StringRelatedField(many=True)

    class Meta:
        model = A

This StringRelatedField will return what C models return in __unicode__ method (__str__ method if python 3.x).

EDIT

Now, from your comment, I know that 'posts.Post' is not C model. So you could use SerializerMethodField:

class AsSerializer(serializers.ModelSerializer):
    c_name = serializers.SerializerMethodField()

    def get_c_name(self, obj):
        return obj.user_id.c_set.values('name')  # this will return a list of dicts with B's related C objects.

    class Meta:
        model = A

EDIT

You can always define class methods in your models:

class B(AbstractBaseUser):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=20, unique=True)    
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=40)
    # `resource_id`
    profile_photo = models.ForeignKey('C', null=True)

    def get_profile_photo(self):
        return self.profile_photo.name  # This will return 'C' related object's name

So when you have an A’s objects:

a_object.user_id.get_profile_photo()

Or if you have an B’s object:

b_object.get_profile_photo()

EDIT

You can define a new Serializer for C class:

class CsSerializer(serializers.Serializer):

    class Meta:
        model = C

Then in your AsSerializer

class AsSerializer(serializers.ModelSerializer):
    c_name = serializers.SerializerMethodField()

    def get_c_name(self, obj):
        qs = obj.user_id.c_set.all()
        qs_serialized = CsSerializer(qs, many=True)
        return qs_serialized.data

    class Meta:
        model = A
👤Gocht

Leave a comment