From post man, I’m trying to make POST request to an order API created using django restframework but I’m getting the following error:
product = Product.objects.get(id=i['product']) TypeError: string indices must be integers
The specific point where the error is located is specified in the error but I find difficulty constructing VALID json for the request body. Here is how I’m making the request on postman:
{ "orderItems":{ "product": {"name":"abc", "brand":"def", "image"www.example.com/img", "description":"xyz", "price":"50"}, "qty":"2", "price":"200" }, "shippingAddress": { "address":"abc", "city":"B", "postalCode":"12345", }, "paymentMethod":"monify", "itemPrice":"100" }
Here is the program:
class Product(models.Model): category = models.CharField(max_length=50, choices=Categories.choices, default=Categories.medications) user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, related_name="user_product", null=True) name = models.CharField(max_length=150) brand = models.CharField(max_length=255, default="brand") productClass = models.CharField(max_length=50, null=True, blank=True) image = models.ImageField(upload_to="images/products/") label = models.CharField(max_length=254, default='', blank=True, null=True) price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True) stock = models.IntegerField(null=True, blank=True, default=0) dateCreated = models.DateTimeField(auto_now_add=True) class Order(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, related_name="user_order", null=True) paymentMethod = models.CharField(max_length=200, null=True, blank=True) dateCreated = models.DateTimeField(auto_now_add=True) def __str__(self): return str(self.dateCreated) models.py class OrderItem(models.Model): product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True) image = models.CharField(max_length=200, null=True, blank=True) order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True) name = models.CharField(max_length=200, null=True, blank=True) qty = models.IntegerField(null=True, blank=True, default=0) price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True) def __str__(self): return str(self.name)
The view I’, trying to test is shown below:
def addOrderItems(request): user = request.user data = request.data orderItems = data['orderItems'] if orderItems and len(orderItems) == 0: return Response({'detail': 'Order item was not provided'}, status=status.HTTP_400_BAD_REQUEST) else: # Step 1: Create order order = Order.objects.create( user=user, paymentMethod=data['paymentMethod'], ) #Step 2: Create shipping address shipping = ShippingAddress.objects.create( order=order, address=data['shippingAddress']['address'], ) # Step 3: Create order items, then set order to orderItem relationship for i in orderItems: product = Product.objects.get(id=i['product']) item = OrderItem.objects.create( product=product, order=order, name=product.name, qty=i['qty'], price=i['price'], image=product.image.url, ) # Step 4: Update stock product.countInStock -= item.qty product.save() serializer = OrderSerializer(order, many=False) return Response(serializer.data)
Any hint on this is well appreciated
Advertisement
Answer
I think the payload is not correct. Now the whole product data is uploaded, but it should be changed into the product_id
. Because in the view, it is being considered as the id field like Product.objects.get(id=i['product'])
.
So the solution is like the following. First, the payload should be changed.
{ "orderItems":[{ "product_id": 3, // here I changed "qty":"2", "price":"200" }], "shippingAddress": { "address":"abc", "city":"B", "postalCode":"12345", }, "paymentMethod":"monify", "itemPrice":"100" }
And in the addOrderItems
function,
def addOrderItems(request): ... if orderItems and len(orderItems) == 0: ... else: ... # Step 3: Create order items, then set order to orderItem relationship for i in orderItems: product = Product.objects.get(id=i['product_id']) ...