【问题标题】:Create JSON Response in Django with Model使用模型在 Django 中创建 JSON 响应
【发布时间】:2012-09-15 05:42:43
【问题描述】:

我在这里遇到了一些问题。我正在尝试返回由消息和模型实例组成的 JSON 响应:

   class MachineModel(models.Model):
       name = models.CharField(max_length=64, blank=False)
       description = models.CharField(max_length=64, blank=False)
       manufacturer = models.ForeignKey(Manufacturer)
       added_by = models.ForeignKey(User, related_name='%(app_label)s_%(class)s_added_by')
       creation_date = models.DateTimeField(auto_now_add=True)
       last_modified = models.DateTimeField(auto_now=True)

    machine_model_model = form.save(commit=False)
    r_user = request.user.userprofile
    machine_model_model.manufacturer_id = manuf_id
    machine_model_model.added_by_id = request.user.id
    machine_model_model.save()
    alert_message = " The'%s' model " % machine_model_model.name
    alert_message += ("for '%s' " % machine_model_model.manufacturer)
    alert_message += "was was successfully created!"
    test = simplejson.dumps(list(machine_model_model))
    data = [{'message': alert_message, 'model': test}]
    response = JSONResponse(data, {}, 'application/json')


class JSONResponse(HttpResponse):
"""JSON response class."""
    def __init__(self, obj='', json_opts={}, mimetype="application/json", *args, **kwargs):
        content = simplejson.dumps(obj, **json_opts)
        super(JSONResponse,self).__init__(content, mimetype, *args, **kwargs)

但我不断得到:

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 178, in default
raise TypeError(repr(o) + " is not JSON serializable")

TypeError: <MachineModel: "Test12"> is not JSON serializable

这是为什么呢?我以前见过:

models = Model.objects.filter(manufacturer_id=m_id)
json = simplejson.dumps(models)

这行得通...有什么区别?!

谢谢!

【问题讨论】:

    标签: python django json django-models django-serializer


    【解决方案1】:

    您应该使用django serializers 而不是simplejson

    例如,这会返回正确的序列化数据:

    from django.core import serializers
    # serialize queryset
    serialized_queryset = serializers.serialize('json', some_queryset)
    # serialize object
    serialized_object = serializers.serialize('json', [some_object,])
    

    【讨论】:

    • 我并没有真正得到 JSON 对象...我得到 "[{"pk": 86, "model": "machine_models.machinemodel", "fields": {"name": “MX10”、“描述”:“大声笑”、“creation_date”:“2012-09-23T16:50:35.709Z”、“last_modified”:“2012-09-23T16:50:35.709Z”、“add_by”: 2、“制造商”:“1”}}]”
    • 实际上是 JSON 对象。您可以在模板上反序列化它。通过jquery,例如:jQuery.parseJSON(response),返回一个javascript字典。
    • 好的,很好用!但我总是得到一个数组(在 JQuery 中,我必须取第一个 [0] ......这正常吗?!这也有点烦人。你会推荐一个 REST Api 吗?!
    • 由于 serialize 方法的第二个参数可以是任何产生 Django 模型实例的迭代器(取自文档),我不知道任何其他方法可以处理单个模型实例序列化.另外,请查看此relative question。关于 REST Api - 抱歉,我在这方面不胜任。顺便说一句,我在我的项目中使用相同的 descriptions :-)
    【解决方案2】:

    方法一:使用Django的python序列化器

    我认为this answer 不会返回 JSON 或 Python dict/list 对象。因此,请使用格式 python 而不是 json

    from django.core import serializers
    # serialize queryset
    serialized_queryset = serializers.serialize('python', some_queryset)
    # serialize object
    serialized_object = serializers.serialize('python', [some_object,])

    Django 外壳响应

    In [2]: from django.core import serializers                                                                                                                             
    
    In [3]: qs = SomeModel.objects.all()                                                                                                                                    
    
    In [4]: json_res = serializers.serialize('json',qs)                                                                                                                     
    
    In [5]: type(json_res)                                                                                                                                                  
    Out[5]: str
    
    In [6]: python_res = serializers.serialize('python',qs)                                                                                                                 
    
    In [7]: type(python_res)                                                                                                                                                
    Out[7]: list
    
    #views.py
    from django.core import serializers
    from django.http.response import JsonResponse
    
    
    def some_view(request):
        some_queryset = SomeModel.objects.all()
        serialized_queryset = serializers.serialize('python', some_queryset)
        return JsonResponse(serialized_queryset, safe=False)

    方法2:使用Django的values()方法

    直接使用values()方法会抛出TypeError异常,所以将QuerySet转成pythonlist > 如下,

    from django.http.response import JsonResponse
    
    
    def sample_view(request):
        return JsonResponse(list(SomeModel.objects.all().values()), safe=False)

    【讨论】:

    • @Radesh 方法 1 发生了什么?
    • 返回 json 响应包含一些额外的 /" 像这样:[{\"model\": \"api\"
    • @JPG,使用这两种方法中的任何一种都一样吗?这些中的任何一个在性能或其他方面有任何缺点吗?我个人认为使用第二种方法很容易,但也很好奇它是否有任何缺点。
    • 我不太喜欢使用 safe=false,但在我的应用程序中,我能够将列表放入字典中,以使 JsonResponse 序列化程序满意:return JsonResponse({ "someObjects": list(SomeModel.objects.all().values()) })跨度>
    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 2021-04-01
    相关资源
    最近更新 更多