【问题标题】:Django: Serialize to JSON a dictionary with items that can include querysetsDjango:将包含可包含查询集的项目的字典序列化为 JSON
【发布时间】:2015-03-24 11:14:13
【问题描述】:

我以这种方式发送一个 JSON 对象(component_list 是一个 QuerySet):

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

但是我想像这样填写更多信息:

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

但它不起作用,因为 serializers.serialize('json', component_list) 已经是一个 json 结构,我正在尝试使用 json.dumps 再次使其成为 json。

我该如何解决这个问题?

【问题讨论】:

  • 检查它是否有效。首先像这样data['component_list'] = component_list 构建您的字典,然后转储数据

标签: python json django


【解决方案1】:

这行得通吗?

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')

【讨论】:

  • 没有。 /components/filter_results/ 'str' 对象的 AttributeError 没有属性 '_meta'
  • 我也尝试过使用 json.dumps,但 RawQuerySet 有问题(component_list 是 RawQuerySet)
  • 哦,那么queryset.values() 可能会解决您的问题:)
  • 'RawQuerySet' 对象没有属性 'values'
  • 哦.. 可能是[i.__dict__ for i in queryset]
【解决方案2】:

好吧,我找到了自己的解决方案。我想我可以帮助其他人。

我创建了自己的编码器类来尽可能多地格式化查询集。

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)

那么,在我看来功能:

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

【讨论】:

  • 我建议使用 django.core.serializers.json.DjangoJSONEncoder 而不是 python 库。它将允许日期时间的编码。
【解决方案3】:

正如@tburette 建议的那样,通过使用 DjangoJSONEncoder 来改进这一点...

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)

我这样称呼它:

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)

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 2013-10-30
    相关资源
    最近更新 更多