Ruben
Ruben

Reputation: 1091

Django: Serialize to JSON a dictionary with items that can include querysets

I'm sending a JSON object (component_list is a QuerySet) in this way:

data = serializers.serialize('json', component_list)
return HttpResponse(data, content_type='application/json')

However I want to fill more information like this:

data = {}
data['ok'] = True
data['component_list'] = serializers.serialize('json', component_list)
return HttpResponse(json.dumps(data), content_type='application/json')

But it doesn't work since serializers.serialize('json', component_list) is already a json structure and I'm trying to make it json again with json.dumps.

How can I solve this?

Upvotes: 0

Views: 2138

Answers (3)

Ruben
Ruben

Reputation: 1091

Improving this by using DjangoJSONEncoder, as @tburette suggested...

class MyJSONEncoder(DjangoJSONEncoder):
    def default(self, obj):
        if isinstance(obj, QuerySet) or isinstance(obj, RawQuerySet):
            return serializers.serialize('python', obj, ensure_ascii=False, use_natural_foreign_keys=True)
        return super().default(obj)

I call this like:

from common.helpers import MyJSONEncoder

x = Part.objects.filter(description__icontains=q)[:10].only('part_code','description')
y = Part.objects.filter(description__icontains=q).count()
data = {'x': x, 'y': y} 
return JsonResponse(data, encoder=MyJSONEncoder)

Upvotes: 0

Ruben
Ruben

Reputation: 1091

Well, I found myself a solution. I think I can help other people with that.

I created my own encoder class to format the querysets as much as I want.

class MyEncoder(json.JSONEncoder):
    """ json.JSONEncoder extension: handle querysets """
    def default(self, obj):
        if isinstance(obj, QuerySet) or isinstance(obj, RawQuerySet):
            return serializers.serialize('python', obj, ensure_ascii=False)
        return json.JSONEncoder.default(self, obj)

then, in my view function:

data['ok'] = True
data['component_list'] = component_list
return HttpResponse(json.dumps(data, cls=MyEncoder),  content_type='application/json')

Upvotes: 0

itzMEonTV
itzMEonTV

Reputation: 20359

Did this work?

data = {}
data['ok'] = True
data['component_list'] = component_list
data = serializers.serialize('json', data) # or json.dumps(data)
return HttpResponse(data, content_type='application/json')

Upvotes: 1

Related Questions