方法对象不是 JSON 可序列化的

Posted

技术标签:

【中文标题】方法对象不是 JSON 可序列化的【英文标题】:method object is not JSON serializable 【发布时间】:2018-06-09 01:02:26 【问题描述】:

当购物车项目被删除时,我正在使用 ajax 来刷新购物车项目。它运作良好,如果我不使用图像响应对象,否则我会收到错误method object is not JSON serializable。如果我将model_to_dict 用于图像部分,则会收到错误'function' object has no attribute '_meta'

这里是代码

def cart_detail_api_view(request):
    cart_obj, new_obj = Cart.objects.new_or_get(request)
    products = [
            "id": x.id,
            "url": x.get_absolute_url(),
            "name": x.name,
            "price": x.price,
            "image": x.first_image
            
            for x in cart_obj.furnitures.all()]
    cart_data  = "products": products, "subtotal": cart_obj.sub_total, "total": cart_obj.total
    return JsonResponse(cart_data)

class Furniture(models.Model):
    name = models.CharField(max_length=100, blank=True, null=True)
    manufacturer = models.ForeignKey(Manufacturer, blank=True, null=True)
    slug = models.SlugField(max_length=200, unique=True)

    def __str__(self):
        return self.name

    def first_image(self):
        """
        Return first image of the furniture otherwise default image
        """
        if self.furniture_pics:
            return self.furniture_pics.first()
        return '/static/img/4niture.jpg'

class Cart(models.Model):
    user = models.ForeignKey(User, null=True, blank=True)
    furnitures = models.ManyToManyField(Furniture, blank=True)

x.first_image 包装到model_to_dict 时出现'function' object has no attribute '_meta' 错误

我该如何解决这个问题?

更新

class FurniturePic(models.Model):
    """
    Represents furniture picture
    """
    furniture = models.ForeignKey(Furniture, related_name='furniture_pics')
    url = models.ImageField(upload_to=upload_image_path)

【问题讨论】:

【参考方案1】:

如您所知,问题在于:

"image": x.first_image

first_image 是一个函数,因此无法转换为 JSON。您要做的是序列化first_image 返回的值。因此,为此,您需要调用这个函数:

"image": x.first_image() # note the brackets

此外,我还注意到另一个问题,在:

return self.furniture_pics.first() # will return the image object; will cause error

因此,您必须将其更改为:

return self.furniture_pics.first().url # will return the url of the image

更新:

self.furniture_pics.first().url 将返回FurniturePic.url,这是一个ImageField。您需要该图片的 url 进行序列化。你必须这样做:

return self.furniture_pics.first().url.url # call url of `url`

如您所见,这变得令人困惑。我建议将FurniturePic.url 字段的名称更改为FurniturePic.image。但是,请随意忽略它。

【讨论】:

这样我得到了Object of type 'FurniturePic' is not JSON serializable。我很犹豫在一个问题中显示不同类型的错误:) 也试过 x.first_image().url 抛出Object of type 'ImageFieldFile' is not JSON serializable这个错误 不是self.furniture_pics.first().urlx.first_image().url 一样吗? @pri 并非总是如此。如果self.furniture_pics 不存在,first_image() 将返回一个字符串。在这种情况下,x.first_image().url 将引发错误。但有趣的是,您现在遇到了不同的错误。 self.furniture_pics 是另一个模型的 ManyToMany 字段吗? 谢谢,命名有时会带来很大的麻烦。我很欣赏你的建议,和你一起去。再次感谢,它现在工作了。

以上是关于方法对象不是 JSON 可序列化的的主要内容,如果未能解决你的问题,请参考以下文章

TypeError:X 类型的对象不是 JSON 可序列化的

TypeError:“float32”类型的对象不是 JSON 可序列化的 [重复]

对象不是 JSON 可序列化的

QuerySet 类型的对象不是 JSON 可序列化的 Django

[错误]:返回的对象不是 JSON 可序列化的

Celery EncodeError(TypeError('响应类型的对象不是 JSON 可序列化的'))