Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create nested serializer of same type with depth option support

Assume there is a child and parent relation in models, such as:

class Foo(models.Model):
  parent = models.ForeignKey('Foo', related_name='children')

Now I want to have a serializer to show children of a Foo object, something like this:

class FooSerializer(serializers.ModelSerializer):
  children = FooSerializer(many=True)
  class Meta:
    model = Foo
    fields = '__all__'

But this gives me error that it does not recognize FooSerializer when creating that class which is correct regarding the way python parses the class. How could I implement such relation and have a serializer to get its children. I must mention that I want to able to use depth option of nested serializer.

I am using django 2.2.7 and rest framework 3.10.1.

Edit

There may be some numbers of nested levels which it must be stopped using depth option, after some levels it must be flatten, so I wanted to able to use depth option along nested serializer.

like image 480
motam Avatar asked Jan 31 '26 18:01

motam


1 Answers

depth attribute is for ForeignKey relationships, In your case, it's reverse-FK relation, So it won't work


You can achieve the depth like feature by using multiple serializer in Nested configuration.

Example 1: result similar to depth=1

class FooBaseSerializerLevel1(serializers.ModelSerializer):
    class Meta:
        model = Foo
        fields = '__all__'


class FooBaseSerializerLevel0(serializers.ModelSerializer):
    children = FooBaseSerializerLevel1(many=True)

    class Meta:
        model = Foo
        fields = '__all__'

Example 2: result similar to depth=2

class FooBaseSerializerLevel2(serializers.ModelSerializer):
    class Meta:
        model = Foo
        fields = '__all__'


class FooBaseSerializerLevel1(serializers.ModelSerializer):
    children = FooBaseSerializerLevel2(many=True)

    class Meta:
        model = Foo
        fields = '__all__'


class FooBaseSerializerLevel0(serializers.ModelSerializer):
    children = FooBaseSerializerLevel1(many=True)

    class Meta:
        model = Foo
        fields = '__all__'

The key point is that, do not define the children where you want to stop the nested effect

like image 85
JPG Avatar answered Feb 03 '26 07:02

JPG