【问题标题】:How to serialize empty ImageField to JsonResponse?如何将空 ImageField 序列化为 JsonResponse?
【发布时间】:2017-03-30 14:32:54
【问题描述】:

我有一个模型:

class Item(models.Model):
    title = models.TextField(verbose_name='Title', default='Default title')
    photo = models.ImageField(verbose_name='Photo',upload_to='media/',blank=True)

    def __str__(self):
        return self.title

我正在尝试将此模型对象序列化为前端的 JSON 响应。这是我的测试视图:

from app.models import Item
from django.forms.models import model_to_dict
from django.http import JsonResponse

def get(self, request, *args, **kwargs):
    item_object = Item.objects.first()
    to_json = model_to_dict(item_object)
    return JsonResponse(to_json)

当我创建没有照片字段的 Item 对象时(从 django shell 没有下载真实文件,这个字段不是必需的),JsonResponse 抛出 TypeError: is not JSON serializable

[16/Nov/2016 13:51:15] "GET /items/?item_id=9&shop_id=4 HTTP/1.1" 500 129160
Internal Server Error: /items/
Traceback (most recent call last):
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 39, in inner
    response = get_response(request)
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/home/lamberk/python/picasel/rc_cross_upsell/CrossUpsell/apps/items/views.py", line 54, in get
    'up_sells': up_sells,
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/http/response.py", line 520, in __init__
    data = json.dumps(data, cls=encoder, **json_dumps_params)
  File "/usr/lib/python3.5/json/__init__.py", line 237, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.5/json/encoder.py", line 198, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.5/json/encoder.py", line 256, in iterencode
    return _iterencode(o, 0)
  File "/home/lamberk/python/picasel/rc_cross_upsell/venv/lib/python3.5/site-packages/django/core/serializers/json.py", line 118, in default
    return super(DjangoJSONEncoder, self).default(o)
  File "/usr/lib/python3.5/json/encoder.py", line 179, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: <ImageFieldFile: None> is not JSON serializable

【问题讨论】:

  • 您发布的代码不完整/与您发布的堆栈跟踪不对应。
  • “但如果我还没有下载照片”是什么意思
  • @e4c5 是的,对不起。我编辑了问题。

标签: python json django serialization model


【解决方案1】:

我建议使用自定义 JSON 编码器,类似以下内容:

class CustomEncoder(DjangoJSONEncoder):
    def default(self, obj):
        if isinstance(obj, ImageFieldFile):
            # Do whatever appropriate for your case, like returning None
        return super(CustomEncoder, self).default(obj)

并像这样使用它:

return JsonResponse(to_json, encoder=CustomEncoder)

【讨论】:

    【解决方案2】:

    您可以编写项目序列化程序并使用它来代替 model_to_dict()

    http://www.django-rest-framework.org/api-guide/serializers/

    或者如果你想使用model_to_dict,你可以把你的代码放在if else块中。

    def get(self, request, *args, **kwargs):
        item_object = Item.objects.first()
        if item_object:
            to_json = model_to_dict(item_object)
            return JsonResponse(to_json)
    

    【讨论】:

    • 只为这个特性使用rest_framework包是否合理?此外,问题不在于空对象。它在项目对象中的空白照片ImageField 中。
    • @K.Valentin 如果您在应用程序中不经常使用 ajax 请求,这是不合理的。但是,如果此类 ajax 端点的数量开始增长,或者您决定制作某种 REST API,那么您应该在某个时候考虑一​​下。
    猜你喜欢
    • 2011-11-21
    • 2020-09-14
    • 2017-02-25
    • 2017-06-29
    • 2017-03-21
    • 1970-01-01
    • 2021-03-03
    • 2014-05-22
    • 1970-01-01
    相关资源
    最近更新 更多