Search code examples
pythondjangoelasticsearchdjango-rest-framework

'InnerDoc' object has no attribute 'pk'


I'm encountering an issue with Elasticsearch-dsl when trying to use a custom serializer with Django REST framework. The error message I'm getting is:

'InnerDoc' object has no attribute 'pk'

This error originates in the line serializer = self.serializer_class(results, many=True) from the following code snippet in my PaginatedElasticSearchAPIView:


class PaginatedElasticSearchAPIView(APIView, LimitOffsetPagination):
    serializer_class = None
    document_class = None

    @abc.abstractmethod
    def generate_q_expression(self, query):
        """This method should be overridden
        and return a Q() expression."""

    def get(self, request, query):
        try:
            q = self.generate_q_expression(query)
            search = self.document_class.search().query(q)
            response = search.execute()

            print(f'Found {response.hits.total.value} hit(s) for query: "{query}"')
            results = self.paginate_queryset(response, request, view=self)
            serializer = self.serializer_class(results, many=True)
            return self.get_paginated_response(serializer.data)
        except Exception as e:
            return HttpResponse(e, status=500)

I've checked my serializer, and it seems to have the primary key ("id") defined correctly:


class OfficeSerializer(serializers.ModelSerializer):
    # ...
    class Meta:
        model = Office
        fields = [
            "id",
            # ...
        ]

My Elasticsearch document, defined as OfficeDocument, also appears to have the primary key ("id") defined correctly:


@registry.register_document
class OfficeDocument(Document):
    # ...
    class Django:
        model = Office
        fields = [
            "id",
            # ...
        ]

Despite this, I was still encountering the "'InnerDoc' object has no attribute 'pk'" error.

Then I recreated all models without explicitly setting ids and removed the ids references in the serializer and document files. The error persists, though.

What could be causing this issue, and how can I resolve it? Any insights or suggestions would be greatly appreciated.


Solution

  • It sure is not pretty, but use to_representation method on your serializer:

    def to_representation(self, instance):
        return super().to_representation(instance.to_dict())
    

    The thing is, object you serialize must be something DRF understands, not InnerDoc.