pretty much lost : self.parent.parent.__class__
<p>I needed to serialize a self referencing hierarchy </p>

<pre><code>class Systm(models.Model):
    ...
    parent = models.ForeignKey('self', on_delete=models.CASCADE, blank = True, null = True, related_name="children")
</code></pre>

<p>and I was able to achieve that with the following code:</p>

<pre><code>class RecursiveField(serializers.Serializer):
    def to_representation(self, value):
        serializer = self.parent.parent.__class__(value, context=self.context)
        return serializer.data

class SystmSerializer(serializers.ModelSerializer):
    children = RecursiveField(many = True, read_only = True)

    class Meta:
        model = models.Systm
        fields = ('id', 'name', 'type', 'children')
</code></pre>

<p>It works and everything is bright except that all I did was to copy and paste the code but no idea how it works and why it works. It is pretty annoying and I want to understand it.<br>
I put '<code>print</code>' commands into '<code>to_representation(...)</code>' but still not clear. I learnt that that there is recursion when the '<code>self.parent.parent.__class__(value, context=self.context)</code>' is executed but not sure why.<br>
I'd be really grateful if somebody could explain it to me.</p>

<p>Thanks,<br>
V.</p>

<p>This basically works by getting the top serializer class and instanciating it to return the serialized value of a child. The <code>parent</code> attribute of a serializer (or field) is the serializer instance that declared this as a field.</p>

<p><code>self.parent</code> is the List Serializer implicitly created when declaring <code>many=True</code> (see <a href="http://www.django-rest-framework.org/api-guide/serializers/#listserializer" rel="nofollow">ListSerializer</a>).
<code>self.parent.parent</code> is the <code>SystmSerializer</code> instance.</p>

<p>My guess is that this code only works because the recursive field has been declared with <code>many=True</code>. If you had <code>child = RecursiveField(read_only = True)</code> the code would be:</p>

<pre><code>class RecursiveField(serializers.Serializer):
    def to_representation(self, value):
        serializer = self.parent.__class__(value, context=self.context)
        return serializer.data
</code></pre>

<p>To make it simple, when you (or DRF) calls <code>serialializer_instance.data</code>, it makes a call to <code>to_representation</code> to serialize the object instance.</p>

<p>Recursion comes into play when doing the <code>SystmSerializer.to_representation</code>:</p>

<ol>
<li>when <code>to_representation(instance)</code> is called, it will call <code>to_representation(field_instance)</code> on every field.</li>
<li>One of these fields is the <code>recursiveField</code>, and more exactly the <a href="http://www.django-rest-framework.org/api-guide/serializers/#listserializer" rel="nofollow">ListSerializer</a> associated with the the <code>recursiveField</code></li>
<li>Calling <code>to_representation</code> on the <a href="http://www.django-rest-framework.org/api-guide/serializers/#listserializer" rel="nofollow">ListSerializer</a> will call <code>recursiveField.to_representation(child)</code> for all children (if any) of the instance.</li>
<li>This is when recursion starts: the implementation of <code>recursiveField.to_representation</code> instanciates a new <code>SystmSerializer</code> instance on the child <code>Systm</code> object and then calls <code>SystmSerializer.data</code> which itself triggers a <code>to_representation</code> call... and you are back to step 1 with a new <code>SystmSerializer</code> instance on the child <code>Systm</code> object.</li>
</ol>

<p>Recursion ends when there are no children. Of course, you can run into endless recursion if a child references an ancestor.</p>

python django django-rest-framework