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.

Upvotes: 5

Views: 12273

Answers (2)

tayyab_fareed
tayyab_fareed

Reputation: 679

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")

Upvotes: 2

neverwalkaloner
neverwalkaloner

Reputation: 47354

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")

Upvotes: 9

Related Questions