我想要返回JSON

时间:2015-10-30 12:27:42

标签: python json django

class UserProfile(AbstractUser):
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)

UserProfile等级。

UserProfile模型扩展了AbstractUser

def get_rank(request):
    users1 = UserProfile.objects.all().order_by('created_at')
    # below code works but variable 'users1' don't work.
    # I want users to JSON. ex) users
    users = '[{"item":"NEFUS"},{"item":"Layer7"},{"item":"Unifox"},{"item":"Focus"},{"item":"Frs"}]'
    return HttpResponse(users , content_type='application/json')

此代码不起作用,我不知道原因。

变量users有效。但变量user1不起作用。

function ajax_get_rank() {
    var temp = new XMLHttpRequest();
    temp.open("GET","/get_rank/");
    temp.onreadystatechange = function() {
        if (temp.readyState === 4 && temp.status === 200) {
            get_rank(temp.responseText);
        }
    }
    temp.send();
}

这是AJAX代码。

function get_rank(rank_array_temp) {
    var temp = JSON.parse(rank_array_temp);
    for( var i = 0 ; i < temp.length; i++) {
        var div_temp = document.createElement("div");
        div_temp.className = "rank"
        var out = "";
        out += "\
            <div class = 'rank'>\
                <span class = 'grade'>\
                    <span>"+parseInt(i+1)+".</span>\
                </span>\
                <span class = 'item_name'>\
                    <span>"+temp[i].item+"</span>\
                </span>\
            </div>\
        ";

        div_temp.innerHTML = out;
        rank_list.appendChild(div_temp);
    }
}

这是主要的JavaScript代码。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:1)

您无法直接序列化django模型对象,这样做会导致TypeError: queryset is not JSON serializable错误。

但您可以使用values获取要显示的字段集合,然后将其序列化:

profiles = UserProfile.objects.all().order_by('created_at') \
                                    .values('field1', 'field2')

users1 = json.dumps(profiles)

请注意,DateTimeDate等字段不是json可序列化的。你需要的是:

from django.core.serializers.json import DjangoJSONEncoder
users1 = json.dumps(profiles, cls=DjangoJSONEncoder)

答案 1 :(得分:0)

直接将对象直接序列化/反序列化到JSOn实际上不是一个好方法,因为:

  1. 对象会有问题,因为它们没有关于如何将该特定对象序列化为JSON
  2. 的描述符
  3. 当您尝试转换values之类的特殊类型时,使用values_listDecimal会有问题,因为JSON没有Decimal类型。
  4. 可能的解决方案:

    1. 很难在python中创建列表或字典,然后将其序列化。您必须将特殊类型解析为基本类型,这些类型也是JSON数据的有效类型,例如将Decimal转换为float

      import json
      height = Decimal("1.78")
      my_dict = {"Name": "Jason", "Age": 16, height: float(height)}
      json.loads(my_dict)
      
    2. 或者@ShangWang提到,您可以使用DjangoJSONEncoder对python特定类型进行编码而不会出错。

      1. 使用Django serializers进行序列化/反序列化。你可以专门研究哪些领域可以被序列化。

        from django.core import serializers
        data = serializers.serialize("json", SomeModel.objects.all())
        
        data = serializers.serialize('json', SomeModel.objects.all(), fields=('name','size'))
        
      2. Django序列化器更容易使用,因为它们会将任何有效的python类型序列化为正确的JSON类型。

        django序列化器的输出将是这样的:

        [
            {
                "pk": "4b678b301dfd8a4e0dad910de3ae245b",
                "model": "sessions.session",
                "fields": {
                    "expire_date": "2013-01-16T08:16:59.844Z",
                    ...
                }
            }
        ]
        

        因此,您可以从每个JSON对象的fields键获取字段和值。您可以查看文档以获取更多信息。