将 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.serializefields
选项,没有选择相关模型的列/字段。有人遇到过同样的情况吗?【参考方案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 对象的主要内容,如果未能解决你的问题,请参考以下文章