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.
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.