将 django ValuesQuerySet 转换为 json 对象

Posted

技术标签:

【中文标题】将 django ValuesQuerySet 转换为 json 对象【英文标题】:Converting a django ValuesQuerySet to a json object 【发布时间】:2011-09-29 21:06:35 【问题描述】:

我正在尝试使用 Django 中的 ValuesQuerySet 功能将查询返回的字段数限制为仅我需要的字段数。我想将此数据集序列化为 JSON 对象但是,Django 不断抛出错误。下面我包含了我的代码和我收到的错误:

objectList = ConventionCard.objects.values('fileName','id').filter(ownerUser = user)
data = serializers.serialize('json', objectList)
return HttpResponse(data, mimetype='application/javascript')

错误:

Exception Type:     AttributeError
Exception Value:    'dict' object has no attribute '_meta'
Exception Location:     C:\Python27\lib\site-packages\django\core\serializers\base.py in serialize, line 41

谢谢!

【问题讨论】:

你为什么使用values()?这使得 dict 对象不容易被序列化。 我不想要我的整个对象。我只想要两个字段。价值观似乎是做到这一点的方法。有没有更好的办法? 由于values 不起作用,说它“似乎是这样做的方法”不可能是真的。如果您只想要两个字段,请更新问题非常非常清楚地说明。问题不清楚。 @S.Lott Values 完全符合它的预期:它返回字段的子集。不起作用的是结果对象的序列化。 @S.Lott “我正在尝试使用 Django 中的 ValuesQuerySet 功能将查询返回的字段数限制为我需要的字段数。”问题很清楚。 【参考方案1】:

在使用上面的list() 方法时,我继续收到dict 对象没有属性_meta 错误。但是我发现 this snippet 可以解决问题

def ValuesQuerySetToDict(vqs):
    return [item for item in vqs]

# Usage
data = MyModel.objects.values('id','title','...','...')
data_dict = ValuesQuerySetToDict(data)
data_json = simplejson.dumps(data_dict)

【讨论】:

模块 simplejson 在 Django 1.5 中是 removed。另一种方法是简单地import json,然后使用json.dumps(data_dict),答案与预期一致。 这需要更高,因为序列化程序有两个缺陷。 1. rest_framework 也有序列化器,所以你必须 from django.core import serializers as emily,第二个是序列化器在这样的查询集上不起作用: statement_line.objects.select_related('ae').values(' ae__opp_own', 'cur','ae_id').annotate(tots=Sum('amt'))【参考方案2】:

通过 serialize 方法使用 QuerySet 在您的值列表中尝试 subsetting the fields:

from django.core import serializers
objectQuerySet = ConventionCard.objects.filter(ownerUser = user)
data = serializers.serialize('json', objectQuerySet, fields=('fileName','id'))

【讨论】:

不理想,因为查询在只需要这两个字段时会提取所有列数据。 当我尝试这个东西时,我注意到,serializers.serialize fields 选项,没有选择相关模型的列/字段。有人遇到过同样的情况吗?【参考方案3】:

只是添加一些我发现的细节:

当我尝试@ars 回答指定字段时,例如:

s_logs = serializers.serialize("json", logs, fields=('user', 'action', 'time'))

我明白了:

["pk": 520, "model": "audit.auditlog", "fields": "user": 3, "action": "create", "time":"2012-12-16T12:13:45.540", ... ]

这不是我想要的值的简单序列化。

所以我尝试了@Aaron 提出的解决方案,将 valuesqueryset 转换为列表,第一次没有工作,因为默认编码器无法处理浮点数或日期时间对象。

所以我使用@Aaron 解决方案,但使用 django 的序列化程序 (DjangoJSONEncoder) 使用的 JSON 编码器,将其作为 kwarg 传递给simplejson.dumps(),如下所示:

s_logs = list(logs.values('user', 'ip', 'object_name', 'object_type', 'action', 'time'))

return HttpResponse(simplejson.dumps( s_logs, cls=DjangoJSONEncoder ), mimetype='application/javascript')

【讨论】:

如果您使用的是 simplejson > 2.1,请查看此问题:github.com/simplejson/simplejson/issues/37 鉴于该问题,可能必须继承 simplejson.JSONEncoder 而不是 json.JSONEncoder【参考方案4】:

首先将 ValuesQuerySet 转换为列表:

query_set = ConventionCard.objects.values('fileName','id').filter(ownerUser = user)

list(query_set)

按照 ars 的建议删除 values 调用会导致经理从表中提取所有列,而不仅仅是您需要的两列。

【讨论】:

出色的答案。效果很好。 它在我的环境中不起作用(Python 3.4、Django 1.8.3)。

以上是关于将 django ValuesQuerySet 转换为 json 对象的主要内容,如果未能解决你的问题,请参考以下文章

Django objects.values

如何过滤django模板中的特殊字符

在这个方法中如何传递参数?

(转)Django学习之 第二章:Django快速上手

复现CVE-2017-7233(Django url跳转漏洞)

(转)Django 数据库