Python 序列化 (到 JSON) 问题

4 投票
1 回答
2422 浏览
提问于 2025-04-17 01:21

我对Python还不太熟悉,所以请多包涵。我正在Django中写一个AJAX处理程序。到目前为止,一切都挺顺利的。但我在这一部分卡了快一天了。我想返回一个包含字典的JSON字符串,而这个字典里又包含一个查询集(queryset):

#
# models.py
#

class Project(models.Model):
  unique_name  = models.CharField(max_length=32, unique=True)
  title        = models.CharField(max_length=255, blank=True)
  description  = models.TextField('project description', blank=True)
  project_date = models.DateField('Project completion date')
  published    = models.BooleanField()

class ProjectImage(models.Model):
  project      = models.ForeignKey('Project', related_name='images')
  image        = models.ImageField(upload_to=get_image_path)
  title        = models.CharField(max_length=255)
  sort_metric  = models.IntegerField()


#
# views.py
#
...
projects = Project.Project.objects.filter(published=True)
...
response_dict({
  'success' : True,
  'maxGroups' : 5, # the result of some analysis on the projects queryset
  'projects' : projects
});

# This one works if I remove 'projects' from the dict
# response = json.dumps( response_dict )

# This one works only on projects
# response = serializers.serialize( 'json', response_dict, relations=('images') )

return HttpResponse( response, mimetype='application/javascript' )

我把两个序列化的代码行注释掉了,因为:

  1. 第一个序列化方法似乎只适用于“简单”的字典,而因为我的字典里包含了projects,所以它出错了,提示[<Project: Project object>] is not JSON serializable,意思是这个项目对象不能被转换成JSON格式。
  2. 第二个序列化方法似乎只适用于查询集或模型,而我的字典的“外层”部分不是模型,所以它报错说'str' object has no attribute '_meta',意思是字符串对象没有'_meta'这个属性。需要注意的是,我使用的是wadofstuff的序列化器,原本以为它能处理我模型中定义的“一对多”关系。但即使我只序列化projects,也没有输出任何ProjectImages。

问题1:序列化整个response_dict的最佳方法是什么?我肯定不是第一个想这样做的人,对吧?

问题2:为什么我无法让多对一的关系正常工作?

非常感谢你的帮助。

更新:我刚找到这个链接:Django JSON Serialization with Mixed Django models and a Dictionary,看起来很有希望,但我还是遇到了'QuerySet' object has no attribute '_meta'的错误。=(

1 个回答

1

你不能那样把一个Python对象转成可保存的格式。Django的文档里有关于该怎么做的说明。

https://docs.djangoproject.com/en/dev/topics/serialization/#id2

这里有个关键的部分需要注意:

json_serializer.serialize(queryset, ensure_ascii=False, stream=response)

撰写回答