djangodjango-rest-frameworkdrf-nested-routers

How to serialize the Infinite-depth nesting example using drf-nested-routers?


I am quite new to django-rest-framework. I am trying to combine the examples infinite-depth nesting and hyperlinks for nested resources in drf-nested-routers

I added a MailReply object just to try the infinite-depth nesting. When i try to access recipients it gives me this AttributeError.

AttributeError at /api/clients/1/maildrops/1/recipients/
'MailRecipient' object has no attribute 'maildrop'

serializers.py

class MailReplySerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'mailrecipient_pk' : 'mailrecipient__pk',
    }
    class Meta:
        model = MailReply
        fields = ('id','url','title',)
class MailRecipientMailReplySerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'mailrecipient_pk' : 'mailrecipient__pk',
    }
    class Meta:
        model = MailReply
        fields = ('url','title')  
class MailRecipientSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'maildrop_pk' : 'maildrop__pk',
    }
    class Meta:
        model = MailRecipient
        fields = ('id','url','name','mailreplies')
    mailreplies = MailRecipientMailReplySerializer(many=True, read_only=True)
class MailDropMailRecipientSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'maildrop_pk' : 'maildrop__pk'
    }
    class Meta:
        model = MailRecipient
        fields = ('url','name')   
class MailDropSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'client_pk' : 'client__pk'
    }
    class Meta:
        model = MailDrop
        fields = ('id','url','title','recipients')
    recipients = MailDropMailRecipientSerializer(many=True, read_only=True)
class ClientMailDropSerializer(NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'client_pk' : 'client__pk',
    }
    class Meta:
        model = MailDrop
        fields = ('url','title',)    
class ClientSerializer(HyperlinkedModelSerializer):
    class Meta:
        model = Client
        fields = ('id','url','name','maildrops')
    maildrops =ClientMailDropSerializer(many=True, read_only=True)

views.py

    class ClientViewSet(viewsets.ViewSet):
        serializer_class = ClientSerializer
        queryset = Client.objects.all()
        def list(self, request,):
            queryset = Client.objects.filter()
            serializer = ClientSerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)

        def retrieve(self, request, pk=None):
            queryset = Client.objects.filter()
            client = get_object_or_404(queryset, pk=pk)
            serializer = ClientSerializer(client, context={'request': request})
            return Response(serializer.data)

    class MailDropViewSet(viewsets.ViewSet):
        serializer_class = MailDropSerializer

        def list(self, request, client_pk=None):
            queryset = MailDrop.objects.filter(client=client_pk)
            serializer = MailDropSerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)

        def retrieve(self, request, pk=None, client_pk=None):
            queryset = MailDrop.objects.filter(pk=pk, client=client_pk)
            maildrop = get_object_or_404(queryset, pk=pk)
            serializer = MailDropSerializer(maildrop, context={'request': request})
            return Response(serializer.data)

    class MailRecipientViewSet(viewsets.ViewSet):
        serializer_class = MailRecipientSerializer

        def list(self, request, client_pk=None, maildrop_pk=None):
            queryset = MailRecipient.objects.filter(mail_drop__client=client_pk, mail_drop=maildrop_pk)
            serializer = MailRecipientSerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)

        def retrieve(self, request, pk=None, client_pk=None, maildrop_pk=None):
            queryset = MailRecipient.objects.filter(pk=pk, mail_drop=maildrop_pk, mail_drop__client=client_pk)
            maildrop = get_object_or_404(queryset, pk=pk)
            serializer = MailRecipientSerializer(maildrop, context={'request': request})
            return Response(serializer.data)

    class MailReplyViewSet(viewsets.ViewSet):
        serializer_class = MailReplySerializer

        def list(self, request, client_pk=None, maildrop_pk=None, mailrecipient_pk=None):
            queryset = MailReply.objects.filter(mail_recipient=mailrecipient_pk, mail_recipient__mail_drop=maildrop_pk, mail_recipient__mail_drop__client=client_pk)
            serializer = MailReplySerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)

        def retrieve(self, request, pk=None, client_pk=None, maildrop_pk=None, mailrecipient_pk=None):
            queryset = MailReply.objects.filter(pk=pk, mail_recipient=mailrecipient_pk, mail_recipient__mail_drop=maildrop_pk, mail_recipient__mail_drop__client=client_pk)
            mailreply = get_object_or_404(queryset, pk=pk)
            serializer = MailReplySerializer(mailreply, context={'request': request})
            return Response(serializer.data)

Any advice or examples is greatly appreciated, thanks in advance.


Solution

  • The problem was actually in my models instead of maildrop i was using mail_drop as an attribute for MailRecipient.

    Here is the working code.

    serializers.py

    class MailReplySerializer(NestedHyperlinkedModelSerializer):
        parent_lookup_kwargs = {
            'client_pk' : 'mail_recipient__mail_drop__client__pk', 'maildrop_pk' : 'mail_recipient__mail_drop__pk', 'mailrecipient_pk' : 'mail_recipient__pk'
        }
        class Meta:
            model = MailReply
            fields = ('id','url','title',)
    class MailRecipientMailReplySerializer(NestedHyperlinkedModelSerializer):
        parent_lookup_kwargs = {
            'client_pk' : 'mail_recipient__mail_drop__client__pk', 'maildrop_pk' : 'mail_recipient__mail_drop__pk', 'mailrecipient_pk' : 'mail_recipient__pk'
        }
        class Meta:
            model = MailReply
            fields = ('url','title')  
    class MailRecipientSerializer(NestedHyperlinkedModelSerializer):
        parent_lookup_kwargs = {
            'client_pk' : 'mail_drop__client__pk', 'maildrop_pk' : 'mail_drop__pk'
        }
        class Meta:
            model = MailRecipient
            fields = ('id','url','name','mailreplies')
        mailreplies = MailRecipientMailReplySerializer(many=True, read_only=True)
    class MailDropMailRecipientSerializer(NestedHyperlinkedModelSerializer):
        parent_lookup_kwargs = {
            'client_pk' : 'mail_drop__client__pk', 'maildrop_pk' : 'mail_drop__pk'
        }
        class Meta:
            model = MailRecipient
            fields = ('url','name')   
    class MailDropSerializer(NestedHyperlinkedModelSerializer):
        parent_lookup_kwargs = {
            'client_pk' : 'client__pk'
        }
        class Meta:
            model = MailDrop
            fields = ('id','url','title','recipients')
        recipients = MailDropMailRecipientSerializer(many=True, read_only=True)
    class ClientMailDropSerializer(NestedHyperlinkedModelSerializer):
        parent_lookup_kwargs = {
            'client_pk' : 'client__pk',
        }
        class Meta:
            model = MailDrop
            fields = ('url','title',)    
    class ClientSerializer(HyperlinkedModelSerializer):
        class Meta:
            model = Client
            fields = ('id','url','name','maildrops')
        maildrops =ClientMailDropSerializer(many=True, read_only=True)
    

    views.py

    class ClientViewSet(viewsets.ViewSet):
        serializer_class = ClientSerializer
        queryset = Client.objects.all()
        def list(self, request,):
            queryset = Client.objects.filter()
            serializer = ClientSerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)
    
        def retrieve(self, request, pk=None):
            queryset = Client.objects.filter()
            client = get_object_or_404(queryset, pk=pk)
            serializer = ClientSerializer(client, context={'request': request})
            return Response(serializer.data)
    
    class MailDropViewSet(viewsets.ViewSet):
        serializer_class = MailDropSerializer
    
        def list(self, request, client_pk=None):
            queryset = MailDrop.objects.filter(client=client_pk)
            serializer = MailDropSerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)
    
        def retrieve(self, request, pk=None, client_pk=None):
            queryset = MailDrop.objects.filter(pk=pk, client=client_pk)
            maildrop = get_object_or_404(queryset, pk=pk)
            serializer = MailDropSerializer(maildrop, context={'request': request})
            return Response(serializer.data)
    
    class MailRecipientViewSet(viewsets.ViewSet):
        serializer_class = MailRecipientSerializer
    
        def list(self, request, client_pk=None, maildrop_pk=None):
            queryset = MailRecipient.objects.filter(mail_drop__client=client_pk, mail_drop=maildrop_pk)
            serializer = MailRecipientSerializer(queryset, many=True, context={'request': request})
            return Response(serializer.data)
    
        def retrieve(self, request, pk=None, client_pk=None, maildrop_pk=None):
           queryset = MailRecipient.objects.filter(pk=pk, mail_drop=maildrop_pk, mail_drop__client=client_pk)
           mailrecipient = get_object_or_404(queryset, pk=pk)
           serializer = MailRecipientSerializer(mailrecipient, context={'request': request})
           return Response(serializer.data)
    
    class MailReplyViewSet(viewsets.ViewSet):
       serializer_class = MailReplySerializer
    
       def list(self, request, client_pk=None, maildrop_pk=None, mailrecipient_pk=None):
          queryset = MailReply.objects.filter(mail_recipient=mailrecipient_pk, mail_recipient__mail_drop=maildrop_pk, mail_recipient__mail_drop__client=client_pk)
          serializer = MailReplySerializer(queryset, many=True, context={'request': request})
          return Response(serializer.data)
    
       def retrieve(self, request, pk=None, client_pk=None, maildrop_pk=None, mailrecipient_pk=None):
          queryset = MailReply.objects.filter(pk=pk, mail_recipient=mailrecipient_pk, mail_recipient__mail_drop=maildrop_pk, mail_recipient__mail_drop__client=client_pk)
          mailreply = get_object_or_404(queryset, pk=pk)
          serializer = MailReplySerializer(mailreply, context={'request': request})
          return Response(serializer.data)