【问题标题】:Converting a django ValuesQuerySet to a json object将 django ValuesQuerySet 转换为 json 对象
【发布时间】: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 功能将查询返回的字段数限制为我需要的字段数。”问题很清楚。

标签: python django json


【解决方案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')

【讨论】:

【解决方案4】:

首先将 ValuesQuerySet 转换为列表:

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

list(query_set)

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

【讨论】:

  • 出色的答案。效果很好。
  • 它在我的环境中不起作用(Python 3.4、Django 1.8.3)。
猜你喜欢
  • 2014-08-14
  • 2020-12-23
  • 2019-10-21
  • 2017-06-16
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多