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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With