15

I am trying to implement calculation logic in APIView class following this page.
However, I got below error because I tried to serialize queryset, not dictionary as demonstrated in the page.
Does anyone know how I can pass queryset to serializer as argument? If not, are there any way to convert into format which can be serialized by serializer?

{
    "non_field_errors": [
        "Invalid data. Expected a dictionary, but got QuerySet."
    ]
}  

views.py

class envelopeData(APIView):

    def get(self,request,pk):
        #pk=self.kwargs['pk']
        #print (pk)

        glass_json=self.get_serialized(pk,"glass")
        print (glass_json)

    def get_serialized(self,pk,keyword):
        queryset = summary.objects.filter(html__pk=pk).filter(keyword=keyword)
        serializer = summarySerializer(data=queryset) <=get error here
        serializer.is_valid(raise_exception=True)

        data=serializer.validated_data
        return data["json"]

serializer.py

class strToJson(serializers.CharField):

    def to_representation(self,value):
        x=JSON.loads(value)
        return x

class summarySerializer(serializers.ModelSerializer):
    project=serializers.CharField(read_only=True,source="html.project")
    version = serializers.CharField(read_only=True, source="html.version")
    pk = serializers.IntegerField(read_only=True, source="html.pk")
    json = strToJson()
    #json=serializers.JSONField(binary=True)

    class Meta:
        model=summary
        fields=('pk','project','version','json')

2 Answers 2

37

You should be aware of these things,

  1. Since you are passing a QuerySet object, you must not provide the data argument.

  2. QuerySet is a list like object, so you should provide many=True while serialization.

  3. the is_valid() method only is applicable only if you pass a dictionary to the data argument, which is not here.

So, change you get_serialized() method as,

def get_serialized(self, pk, keyword):
    queryset = summary.objects.filter(html__pk=pk).filter(keyword=keyword)
    serializer = summarySerializer(queryset, many=True)
    data = serializer.data
    return data["json"]

References

  1. Dealing with multiple objects in Serializer ---- many=True
  2. is_valid()
Sign up to request clarification or add additional context in comments.

Comments

7

As far as I can see you need to provide serializer class with many=True. As for docs:

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

http://www.django-rest-framework.org/api-guide/serializers/#dealing-with-multiple-objects

So the line that raises error should look this way

serializer = summarySerializer(queryset, many=True)

3 Comments

Thank you for your answer. Implementing many=True, I got error below { "non_field_errors": [ "Expected a list of items but got type \"QuerySet\"." ] }
@KatsuyaObara Could you try serializer = summarySerializer(queryset, many=True)? Mind there is no data parameter name.
I tried serializer = summarySerializer(data=queryset, many=True) but result is same. { "non_field_errors": [ "Expected a list of items but got type \"QuerySet\"." ] }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.