web-dev-qa-db-ja.com

メソッドオブジェクトはJSONシリアル化できません

カートアイテムが削除されたときに、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)

'function' object has no attribute '_meta'x.first_imageにラップしているときにmodel_to_dictエラーが発生します

このような問題を解決するにはどうすればよいですか?

更新しました

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

ご存知のように、問題は次の場所にあります。

_"image": x.first_image
_

_first_image_は関数であるため、JSONに変換できません。あなたがしたいのは、_first_image_によって返された値をシリアル化することです。したがって、そのためには、callこの関数を実行する必要があります。

_"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は、ImageFieldである_FurniturePic.url_を返します。シリアル化するには、その画像のURLが必要です。あなたはこれをしなければならないでしょう:

_return self.furniture_pics.first().url.url # call url of `url`
_

ご覧のとおり、これは混乱を招いています。 _FurniturePic.url_フィールドの名前を_FurniturePic.image_に変更することをお勧めします。ただし、無視してかまいません。

8
xyres