Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object of type 'Product' is not JSON serializable

I'm trying to pull the from my app via Django. The issue is when I call Order Detail via my serializers, I get this error:

TypeError at /api/customer/order/latest/
Object of type 'Product' is not JSON serializable
Request Method: GET
Request URL:    http://localhost:8000/api/customer/order/latest/?access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXX
Django Version: 1.10
Exception Type: TypeError
Exception Value:    
Object of type 'Product' is not JSON serializable

I'm pulling the data from this Model:

class OrderDetail(models.Model):
    order = models.ForeignKey(Order, related_name='order_details')
    product_size = models.ForeignKey(ProductSize)
    quantity = models.IntegerField()
    sub_total = models.FloatField()

    def __str__(self):
        return str(self.id)

# references Prodcut and allows old code to work.
    @property
    def product(self):
        return self.product_size.product

This is what is being pulled:

'order_details': [OrderedDict([('id', 68),
                                ('product_size', 44),
                                ('quantity', 1),
                                ('sub_total', 20.0),
                                ('product', <Product: Bacon Burger - withDrink>)])],
 'status': 'Your Order Is Being Picked Right Off The Plant!',
 'total': 20.0}
request 
<WSGIRequest: GET '/api/customer/order/latest/?access_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXX'>

Serializers:

class OrderDetailSerializer(serializers.ModelSerializer):

    class Meta:
        model = OrderDetail
        fields = ("id", "product_size", "quantity", "sub_total", "product")


class OrderSerializer(serializers.ModelSerializer):
    customer = OrderCustomerSerializer()
    driver = OrderDriverSerializer()
    restaurant = OrderRestaurantSerializer()
    order_details = OrderDetailSerializer(many = True)
    status = serializers.ReadOnlyField(source= "get_status_display")

    class Meta:
        model = Order
        fields = ("id", "customer", "restaurant", "driver", "order_details", "total", "status", "address")

Function for details:

def customer_get_latest_order(request):
    access_token = AccessToken.objects.get(token = request.GET.get("access_token"),
    expires__gt = timezone.now())

    customer = access_token.user.customer
    order = OrderSerializer(Order.objects.filter(customer = customer).last()).data

    return JsonResponse({"order": order})

I'm not sure what needs to be done.

like image 742
Doing Things Occasionally Avatar asked May 08 '18 05:05

Doing Things Occasionally


2 Answers

Since product property of OrderDetail model returns Product object, it cannot be serialized during response process.

To fix it you can just return product.id:

class OrderDetail(models.Model):
    order = models.ForeignKey(Order, related_name='order_details')
    product_size = models.ForeignKey(ProductSize)
    quantity = models.IntegerField()
    sub_total = models.FloatField()

    def __str__(self):
        return str(self.id)

    @property
    def product(self):
        return self.product_size.product.id

Or if you need to have product's details in response you should add one more nested serializer into OrderDetailSerializer:

class ProductSerializer(serializers.ModelSerializer):

    class Meta:
        model = Product
        fields = ("id", "other fields")

class OrderDetailSerializer(serializers.ModelSerializer):
    prodcut = ProductSerializer()

    class Meta:
        model = OrderDetail
        fields = ("id", "product_size", "quantity", "sub_total", "product")
like image 170
neverwalkaloner Avatar answered Sep 28 '22 10:09

neverwalkaloner


You need to create a serializer for the product property that you have declared in the OrderDetail model. If you don't it will give this error because the product property returns an object of class Product and it doesn't know how to serialize it. After creating the serializer do the following

class OrderDetailSerializer(serializers.ModelSerializer):
    product=ProductSerializer(read_only=True, many=False) # you need to do this
    class Meta:
        model = OrderDetail
        fields = ("id", "product_size", "quantity", "sub_total", "product")
like image 29
tayyab_fareed Avatar answered Sep 28 '22 09:09

tayyab_fareed