Django "is not JSON serializable" - ajax, views.py - 如何实现?



我已经阅读了文档,但我不确定如何在 view.py 中为 JSON 对象实现serializer.serialize。 如果有人能帮助我更好地理解这一点。 我的 view.py 中有以下代码:

@user_passes_test(lambda u: u.is_superuser)
def ProjDetails(request):
    proj_id = request.GET['proj_id']
    proj = Proj.objects.filter(id=proj_id)
    role_list = ProjRole.objects.filter(proj=proj)
    proj = {
        "proj": proj,
        "roles": []
    }
    for r in role_list:
         proj['roles'].append(r.id)
    return HttpResponse(json.dumps(proj), content_type='application/json; charset=UTF-8')

我正在尝试用 .ajax 调用它(我仍在研究 ajax,所以它可能不正确):

$('#proj_list #sel_proj').click(function(){
   $('div.sel').removeClass("sel");
   $(this).addClass("sel");
   var project_id = $(this).data('id');
   $.ajax({
       url:'../../proj_details',
       data: {proj_id: proj_id},
       // dataType: 'html',
       success: function(data){
           $('#proj_display').html(data)
       },
       error: function () {
           alert("Failed to find the project!")
       }
});

一旦我让 JSON 调用工作,那么我将更多地关注 ajax。

最大的问题,我收到一个 500 http 错误:

TypeError at ../proj_details
[<Project: Example>] is not JSON serializable

我正在使用 Django 1.7,但我什至在没有任何运气的情况下将SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'添加到我的 settings.py 中。 所以我从 django.core 导入了序列化程序并尝试使用 serializer.serialize ,但我不明白如何实现它,因为我的错误越来越严重。我见过其他帖子有同样的错误,但仍然不理解我的特定要求。

+++++++++

++++++ 编辑 ++

++++++++++++++++

因此,我能够在没有多个错误、循环错误、多个参数错误等的情况下使其工作的唯一方法是:

def ProjDetails(request):
    def date_handler(obj):
        return obj.strftime("%B %d, %Y") if hasattr(obj, 'strftime') else obj
        proj_id = request.GET['proj_id']
        proj = Proj.objects.get(id=proj_id)
        corp = Corp.objects.get(id=proj.corp.id)
        role_list = ProjRole.objects.filter(proj=proj).all()
        proj = {
        "proj": {
             'title': proj.title,
             'id': proj.id,
             'date': proj.date,
             'description': proj.description
        }
        "roles": [],
        "company": {
             'name': corp.name,
             'pic': unicode(corp.pic),
        }
    }
    for r in role_list:
         proj['roles'].append(r.name)
return HttpResponse(json.dumps(proj, default=date_handler), content_type='application/json; charset=UTF-8')

唯一不喜欢的是,我实际上必须手动将我想要的属性从模型中提取到字典中,而不是从模型中提取所有属性,然后我可以选择要在模板中使用的属性。我宁愿不必像上面的例子那样拉动所有内容。 'roles' = []也给我带来了一些小问题,因为当 proj 对象有多个角色时,我似乎无法让它工作。

我喜欢尤金的方法,因为它会更干净,但我似乎无法让它与公司模型一起工作。 proj 表有一个corp_id,但是当我尝试对 proj 对象使用 .value().get() 时,我一直得到corp_id不是属性。 我也不明白如何实现 grzgrzgrz3 的答案。 我通常更多地使用JS,HTML和CSS,并且我是Django/python进行Web开发的新手。

因此,任何提高效率的建议都会很棒。 谢谢!!

Django 模型的实例无法序列化,你应该使用 values() 方法来检索字典而不是类实例。此外,您可以使用 only() 方法仅检索角色的 id 字段:

proj = Proj.objects.filter(id=proj_id).values().get()
role_list = ProjRole.objects.only("id").filter(proj__id=proj_id)
proj = {
    "proj": proj,
    "roles": role_list
}

编写自定义 HttpResponse 并处理所有不可序列化的 python/django 对象。

class HttpJsonResponse(HttpResponse):
    content_type="application/json"

    def __init__(self,data):
        def json_serial(obj):
            """JSON serializer for objects not serializable by default json code"""
            if isinstance(obj, datetime.date):
                serial = obj.isoformat()
                return serial
        json_data = json.dumps(data, indent=4, default=json_serial)
        super(HttpJsonResponse, self).__init__(json_data, self.content_type)

在示例中,函数json_serial datetime.date对象转换为可序列化的字符串对象。

*更新

您可以混合使用这两个答案。

def ProjDetails(request):
    proj_id = request.GET['proj_id']
    proj = Proj.objects.filter(id=proj_id).values().get()
    corp = Corp.objects.filter(id=proj.corp.id).values().get()
    role_list = ProjRole.objects.filter(proj=proj).values().all()
    proj = {
        "proj": proj,
        "roles": role_list,
        "company": corp
    }
    return HttpJsonResponse(proj)

确保导入日期时间模块。

import datetime

而是日期时间类

import datetime.datetime

我的回答,如上所述。 这就是对我有用的东西。

   def ProjDetails(request):
    def date_handler(obj):
        return obj.strftime("%B %d, %Y") if hasattr(obj, 'strftime') else obj
        proj_id = request.GET['proj_id']
        proj = Proj.objects.get(id=proj_id)
        corp = Corp.objects.get(id=proj.corp.id)
        role_list = ProjRole.objects.filter(proj=proj).all()
        proj = {
        "proj": {
             'title': proj.title,
             'id': proj.id,
             'date': proj.date,
             'description': proj.description
        }
        "roles": [],
        "company": {
             'name': corp.name,
             'pic': unicode(corp.pic),
        }
    }
    for r in role_list:
         proj['roles'].append(r.name)
return HttpResponse(json.dumps(proj, default=date_handler), content_type='application/json; charset=UTF-8')

最新更新