Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

method object is not JSON serializable

I am using ajax to refresh the cart items when cart item is removed. It works well, if i don't response object with image otherwise I get an error method object is not JSON serializable. If i use model_to_dict for the image part, i get an error 'function' object has no attribute '_meta'.

here is the code

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)

I get 'function' object has no attribute '_meta' error while wrapping x.first_image to model_to_dict

How do i resolve such issue?

UPDATED

class FurniturePic(models.Model):
    """
    Represents furniture picture
    """
    furniture = models.ForeignKey(Furniture, related_name='furniture_pics')
    url = models.ImageField(upload_to=upload_image_path)
like image 622
pri Avatar asked Dec 28 '17 13:12

pri


1 Answers

The problem, as you know, is at :

"image": x.first_image

first_image is a function, so it can't be converted to JSON. What you want to do is serialize the value returned by first_image. So, for that, you need to call this function:

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

Additionally, I also noticed another issue, at:

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

So, you'll have to change that to:

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

Update:

self.furniture_pics.first().url will return FurniturePic.url which is an ImageField. You need the url of that picture for serialization. You'd have to do this:

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

As you can see, this is getting confusing. I'd suggest changing the FurniturePic.url field's name to FurniturePic.image. But, feel free to ignore it.

like image 74
xyres Avatar answered Sep 20 '22 15:09

xyres