【问题标题】:<Django object > is not JSON serializable<Django 对象> 不是 JSON 可序列化的
【发布时间】:2013-05-23 07:48:40
【问题描述】:

我有以下代码用于序列化查询集;

def render_to_response(self, context, **response_kwargs):

    return HttpResponse(json.simplejson.dumps(list(self.get_queryset())),
                        mimetype="application/json")

以下是我的get_querset()

[{'product': <Product: hederello ()>, u'_id': u'9802', u'_source': {u'code': u'23981', u'facilities': [{u'facility': {u'name': {u'fr': u'G\xe9n\xe9ral', u'en': u'General'}, u'value': {u'fr': [u'bar', u'r\xe9ception ouverte 24h/24', u'chambres non-fumeurs', u'chambres familiales',.........]}]

我需要序列化。但它说无法序列化&lt;Product: hederello ()&gt;。因为列表由 django 对象和 dicts 组成。有任何想法吗 ?

【问题讨论】:

标签: python django json serialization django-class-based-views


【解决方案1】:

在使用模型时解决此问题的另一个好方法是使用values() 函数。

def returnResponse(date):
    response = ScheduledDate.objects.filter(date__startswith=date).values()
    return Response(response)

【讨论】:

    【解决方案2】:

    我们的 js 程序员要求我返回准确的 JSON 格式数据而不是 json 编码的字符串给她。

    下面是解决方案。(这将返回一个可以在浏览器中直接使用/查看的对象)

    import json
    from xxx.models import alert
    from django.core import serializers
    
    def test(request):
        alert_list = alert.objects.all()
    
        tmpJson = serializers.serialize("json",alert_list)
        tmpObj = json.loads(tmpJson)
    
        return HttpResponse(json.dumps(tmpObj))
    

    【讨论】:

    • 只要HttpResponse(tmpObj)会更好
    【解决方案3】:

    simplejsonjson 不能很好地处理 django 对象。

    Django 内置的serializers 只能序列化由 django 对象填充的查询集:

    data = serializers.serialize('json', self.get_queryset())
    return HttpResponse(data, content_type="application/json")
    

    在您的情况下,self.get_queryset() 内部包含 django 对象和 dicts 的混合。

    一种选择是删除self.get_queryset() 中的模型实例,并使用model_to_dict 将它们替换为dicts:

    from django.forms.models import model_to_dict
    
    data = self.get_queryset()
    
    for item in data:
       item['product'] = model_to_dict(item['product'])
    
    return HttpResponse(json.simplejson.dumps(data), mimetype="application/json")
    

    希望对您有所帮助。

    【讨论】:

    • 现在出现错误 --> 'NoneType' object has no attribute 'concrete_model' ... 并使用 Django 1.4+
    • 当模型有日期时间字段时不起作用。
    • 那个解决方案会触发很多查询
    • 要直接在 JS 中使用,只需使用 safe 标记。 stackoverflow.com/a/57939897/4157431
    【解决方案4】:

    最简单的方法是使用JsonResponse

    对于查询集,您应该传递该查询集的 values 列表,如下所示:

    from django.http import JsonResponse
    
    queryset = YourModel.objects.filter(some__filter="some value").values()
    return JsonResponse({"models_to_return": list(queryset)})
    

    【讨论】:

    • 感谢 .values(),在我的情况下,我只需要在过滤器之后添加 .values()
    【解决方案5】:

    从 1.9 版开始 获取 json 的更简单和官方的方式

    from django.http import JsonResponse
    from django.forms.models import model_to_dict
    
    
    return JsonResponse(  model_to_dict(modelinstance) )
    

    【讨论】:

      【解决方案6】:

      我发现使用“.values”方法可以很简单地做到这一点,它还提供了命名字段:

      result_list = list(my_queryset.values('first_named_field', 'second_named_field'))
      return HttpResponse(json.dumps(result_list))
      

      "list" 必须用于获取可迭代的数据,因为 "value queryset" 类型仅在作为可迭代获取时才为 dict。

      文档:https://docs.djangoproject.com/en/1.7/ref/models/querysets/#values

      【讨论】:

      • 这对我来说效果很好。即使错误消息表明它都在一个大列表中,list() 显然仍然需要。
      【解决方案7】:

      首先我在模型中添加了一个 to_dict 方法;

      def to_dict(self):
          return {"name": self.woo, "title": self.foo}
      

      那我有这个;

      class DjangoJSONEncoder(JSONEncoder):
      
          def default(self, obj):
              if isinstance(obj, models.Model):
                  return obj.to_dict()
              return JSONEncoder.default(self, obj)
      
      
      dumps = curry(dumps, cls=DjangoJSONEncoder)
      

      最后使用这个类来序列化我的查询集。

      def render_to_response(self, context, **response_kwargs):
          return HttpResponse(dumps(self.get_queryset()))
      

      效果很好

      【讨论】:

        猜你喜欢
        • 2015-02-24
        • 2014-10-23
        • 2018-09-12
        • 2014-09-21
        • 1970-01-01
        • 2016-04-01
        • 2012-07-02
        • 1970-01-01
        • 2020-03-04
        相关资源
        最近更新 更多