1

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

neowenshun
  • 860
  • 1
  • 7
  • 21
  • Where are you trying to use this data? –  May 20 '20 at 11:29
  • Im trying to use this in my project detail page – neowenshun May 20 '20 at 11:31
  • if you want to response with TransitionApproval data, you need to cover it with serializer. You now trying to return objects instead of json here `return transitions`. Exp: You can create TransitionSerializer. and return `TransitionSerializer(transitions, many=True).data`. Or totally remove methodfield and replace it with TransitionSerializer – Marat Ablayev May 20 '20 at 11:37

1 Answers1

3

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
kamilyrb
  • 2,502
  • 3
  • 10
  • 25
  • Hello there , i have tried the above method , but it seems to give a new error : 'CTEQuerySet' object has no attribute 'object_id' . I used __all__ in my TransitionalApprovalSerializer. It seems that instead of getting the fields from the object itself , its getting the fields from the queryset i passed in , any idea on how to fix this? – neowenshun May 20 '20 at 12:20
  • I think you have `object_id` field inside your `TransitionApproval` model. it throws this error. Have you this field? – kamilyrb May 20 '20 at 12:33
  • Yup its definitely a field within my TransitionApproval model , i actually ran a loop to extract each object out and print out the object id which returned a correct value – neowenshun May 20 '20 at 12:36
  • It seems to try to pluck the object_id field from 'CTESet' object instead of the TransitionApproval object though – neowenshun May 20 '20 at 12:38
  • If you don't need this field you can change `fields = '__all__' ` with `exclude = ['object_id']` in your `TransitionApprovalSerializer` – kamilyrb May 20 '20 at 12:38
  • Hmm , i tried that , the error would go on to the next model field – neowenshun May 20 '20 at 12:40
  • Hello @kamilyrb , thank you for the response , i will give this a vote because i think that this would have solved my issue if not for the CTE manager. Im not too sure how this CTE manager works yet but it does not seem to be compatible with django serializer(?) . The problem can be resolved if i use get_object_or_404 instead of filtering . Hence , this issue seems to be out of bounds of this post. Once again , thanks for your help , i really appreciate it! – neowenshun May 20 '20 at 13:28
  • @neowenshun thank you. unfortunatelly, I have never use CTE manage, so I don't know what is the problem, I hope you can solve it. – kamilyrb May 20 '20 at 20:08