Skip to content
Advertisement

Error in making POST request to django API

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'])
            ...
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement