使用 select_related 将查询中的数据结果序列化为 json
Posted
技术标签:
【中文标题】使用 select_related 将查询中的数据结果序列化为 json【英文标题】:Serializing data results from query with select_related into json 【发布时间】:2014-03-26 12:01:27 【问题描述】:如何将带有 select 的查询的输出序列化为 json ? 当我使用 select_related 对查询中的数据进行序列化时,生成的 json 不包含相关字段数据。
表架构。
from django.db import models
class User(models.Model)
username = models.CharField(max_length=30)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.CharField(max_length=50)
class Userinfo(models.Model)
userId = models.oneToOneField(User)
userImg = models.TextField()
city = models.CharField(max_length=30)
says = models.CharField(max_length=200)
使用选择相关查询
from django.core import serializers
json_serializer = serializers.get_serialier("json")()
uinfo = Userinfo.objects.filter(userId=1).select_related('userId')
response = json_serializer.serialize(uinfo, ensure_ascii=False, indent=2, use_natural_keys=True)
响应的结果是
[
"pk": 1,
"model": "userinfo",
"fields":
"city": "mycity",
"says": "Hi, its me",
"userImg": "profile_img.png",
"userId": [ "user1" ]
]
结果应该是
[
"pk": 1,
"model": "userinfo",
"fields":
"city": "mycity",
"says": "Hi, its me",
"userImg": "profile_img.png",
"userId": [
"username" : "user1",
"first_name" : "User",
"last_name" : "ls1",
"email" : "user1@host.com"
]
]
我使用值而不是选择相关更改了查询,但出现了这个错误
uinfo = Userinfo.objects.filter(userId=1).values('userImg', 'city', 'says', 'userId__username', 'userId__first_name', 'userId__email')
response = json_serializer.serialize(uinfo, ensure_ascii=False, indent=2, use_natural_keys=True)
错误:
concrete_model = obj._meta.concrete_model
AttributeError: 'dict' object has no attribute '_meta'
我也尝试了一些在 *** 上找到的解决方案,但在序列化过程中出现错误
第一种方法
from rest_framework.renderers import JSONRenderer
uinfo = Userinfo.objects.filter(userId=1).select_related('userId')
response = JSONRenderer().render(uinfo)
uinfo 的 type() 是
<class 'django.db.models.query.QuerySet'>
错误:
TypeError: [<Userinfo: Userinfo object>] is not JSON serializable
第二种方法:
from rest_framework.renderers import JSONRenderer
uinfo = Userinfo.objects.filter(userId=1).values('userImg', 'city', 'says', 'userId__username', 'userId__first_name')
response = JSONRenderer().render(uinfo)
并且返回的uinfo的type()是类
<'django.db.models.query.ValuesQuerySet>
错误:
TypeError: ['userImg': u'profile_img.png', 'city': u'mycity', 'says' : u'Hi, its me' 'userId__username': u'user1', 'userId__first_name': u'user'] is not JSON serializable
我还尝试在序列化为 json 之前将查询输出结果转换为字典(使用 https://djangosnippets.org/snippets/2670/),但出现以下错误
uinfo = Userinfo.objects.filter(userId=1).select_related('userId')
uinfodata = deep_dump_instance(uinfo)
错误:
in deep_dump_instance
if (instance.__class__, instance.pk) in seen:
AttributeError: 'QuerySet' object has no attribute 'pk'
【问题讨论】:
【参考方案1】:views.py
from django.utils import simplejson
def convert_to_json():
uinfo = Userinfo.objects.filter(userId_id__in=inner_qs).values('userId__username', 'userImg', 'says', 'userId__first_name', 'city')
lusers = ValuesQuerySetToDict(users)
response = simplejson.dumps(lusers)
return response
def ValuesQuerySetToDict(vqs):
return [item for item in vqs]
【讨论】:
以上是关于使用 select_related 将查询中的数据结果序列化为 json的主要内容,如果未能解决你的问题,请参考以下文章
迭代 Django 中的相关对象:循环查询集或使用单行 select_related(或 prefetch_related)
Django:4个表中的select_related() / prefetch_related()
Django查询优化之select_related和prefetch_related
ORM数据库查询优化only与defer(select_related与prefetch_related)