14

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')
Katsuya Obara
  • 903
  • 3
  • 14
  • 30

2 Answers2

34

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()
JPG
  • 82,442
  • 19
  • 127
  • 206
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)
wiaterb
  • 496
  • 3
  • 8
  • Thank you for your answer. Implementing many=True, I got error below { "non_field_errors": [ "Expected a list of items but got type \"QuerySet\"." ] } – Katsuya Obara Aug 28 '18 at 15:18
  • @KatsuyaObara Could you try `serializer = summarySerializer(queryset, many=True)`? Mind there is no `data` parameter name. – wiaterb Aug 28 '18 at 15:22
  • I tried serializer = summarySerializer(data=queryset, many=True) but result is same. { "non_field_errors": [ "Expected a list of items but got type \"QuerySet\"." ] } – Katsuya Obara Aug 29 '18 at 00:12