使用 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)

pythonのdjango select_related 和 prefetch_related()

Django select_related 查询不会将所有值返回到模板