DRF Methodserializer : Object of type <XXX>is not JSON serializable

932 views Asked by At

i am trying to convert my existing project to the DRF . However im facing the error of :

: Object of type TransitionApproval is not JSON serializable

TransitionApproval object comees from a package called django-river. Here is my code:

class ProjectDetailSerializer(serializers.ModelSerializer):
requirements = CustomerRequirementSerializer(many=True)
transitionApproval = serializers.SerializerMethodField('get_transition_approval')

class Meta:
    model = Project
    fields = '__all__'
    depth = 2

def get_transition_approval(self,project):
    transitions = TransitionApproval.objects.filter(object_id=project.pk).filter(workflow__field_name='project_status')
    print(transitions)
    return transitions

My console prints :

<CTEQuerySet [<TransitionApproval: TransitionApproval object (1)>, <TransitionApproval: TransitionApproval object (2)>, <TransitionApproval: TransitionApproval object (3)>]>

Is there a good way to solve this? I have tried doing this :

class ProjectDetailSerializer(serializers.ModelSerializer):
requirements = CustomerRequirementSerializer(many=True)
transitionApproval = TransitionSerializer(many=True)

class Meta:
    model = Project
    fields = '__all__'
    depth = 2

but it seems that 'transitionApproval' is not an attribute of Project. Im not sure how to resolve this.

Here is my detail page view

class SalesProjectDetailView(RetrieveAPIView):
queryset = SalesProject.objects.all()
serializer_class = SalesProjectDetailSerializer

edits:

I have taken the advise to pass the queryset through a serializer before returning it .

class TransitionApprovalSerializer(serializers.ModelSerializer):
    class Meta:
        model = TransitionApproval
        fields = '__all__'    


class ProjectDetailSerializer(serializers.ModelSerializer):
    transitionApproval = serializers.SerializerMethodField('get_transition_approval')

    class Meta:
        model = Project
        fields = '__all__'
        depth = 2

    def get_transition_approval(self,project):
        transitions = TransitionApproval.objects.filter(object_id=project.pk).filter(workflow__field_name='project_status')
        return TransitionApprovalSerializer(transitions).data

That however returns me an error of :

Traceback (most recent call last):

File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-

packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
    raise exc
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\generics.py", line 208, in get
    return self.retrieve(request, *args, **kwargs)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\mixins.py", line 56, in retrieve
    return Response(serializer.data)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\serializers.py", line 562, in data
    ret = super().data
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\serializers.py", line 529, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\fields.py", line 1905, in to_representation
    return method(value)
  File "C:\Users\dream\Desktop\crmReact\backend\backend\sales\api\serializers.py", line 205, in get_transition_approval
    return TransitionApprovalSerializer(transitions).data
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\serializers.py", line 562, in data
    ret = super().data
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\serializers.py", line 516, in to_representation
    attribute = field.get_attribute(instance)
  File "C:\Users\dream\Desktop\crmReact\backend\react_env\lib\site-packages\rest_framework\fields.py", line 487, in get_attribute
    raise type(exc)(msg)
AttributeError: Got AttributeError when attempting to get a value for field `object_id` on serializer `TransitionApprovalSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `CTEQuerySet` instance.
Original exception text was: 'CTEQuerySet' object has no attribute 'object_id'.

object_id is a field of the TransitionApproval object , but i think the serializer is taking the queryset as the object itself

1

There are 1 answers

8
kamilyrb On BEST ANSWER

You can get this error, because your get_transition_approval method returns queryset TransitionApproval.Querysets couldn't serialize to json directly. You must return serialized data from this method. You can create another serializer and serialize your data with this serializer like that:

class TransitionApprovalSerializer(serializers.ModelSerializer):#your new serializer
    class Meta:
        model = TransitionApproval
        fields = [...]


class ProjectDetailSerializer(serializers.ModelSerializer):
    ....
    def get_transition_approval(self,project):
        transitions = TransitionApproval.objects.filter(object_id=project.pk).filter(workflow__field_name='project_status')
        # you can serialize your data here
        return TransitionApprovalSerializer(transitions).data