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

Django "is not JSON serializable" - ajax, views.py - How to implement?

我已经阅读了文档,但我不确定如何在我的 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,但我什至在我的 settings.py 中添加了 SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer',但没有任何运气。所以我从 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' = [] 也给我带来了一些麻烦,因为当一个项目对象有多个角色时,我似乎无法让它工作。

我喜欢 Eugene 的方法,因为它会更干净,但我似乎无法让它与 corp 模型一起使用。 proj 表有一个 corp_id,但是当我尝试对 proj 对象使用 .value().get() 时,我一直得到 corp_id is not an attribute。我也不明白如何实现 grzgrzgrz3 的答案。我通常更多地使用 JS、HTML 和 CSS,并且我是 Django/python 的网络开发新手。

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

Django 模型的实例无法序列化,您应该使用 values() 方法来检索字典而不是 class 实例。此外,您可以使用 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_serialdatetime.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

改为日期时间class

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')