0

I am trying to create an E-Commerce Website and I am at the Final Step i.e. Placing the Order. So, I am trying to add all the Cart Items into my Shipment model. But I am getting this error.

'QuerySet' object has no attribute 'product'

Here are my models

class Product(models.Model):
    productId = models.AutoField(primary_key=True)
    productName = models.CharField(max_length=200)
    productDescription = models.CharField(max_length=500)
    productRealPrice = models.IntegerField()
    productDiscountedPrice = models.IntegerField()
    productImage = models.ImageField()
    productInformation = RichTextField()
    productTotalQty = models.IntegerField()
    alias = models.CharField(max_length=200)
    url = models.CharField(max_length=200, blank=True, null=True)

class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, null=True, blank=True)
    email = models.EmailField(max_length=100)
    profileImage = models.ImageField(blank=True, null=True, default='profile.png')
    phoneNumber = models.CharField(max_length=10, blank=True, null=True)
    address = models.CharField(max_length=500, blank=True, null=True)


class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
    dateOrdered = models.DateTimeField(auto_now_add=True)
    orderCompleted = models.BooleanField(default=False)
    transactionId = models.AutoField(primary_key=True)


class Cart(models.Model):
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, blank=True, null=True)
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
    quantity = models.IntegerField(default=0, blank=True, null=True)
    dateAdded = models.DateTimeField(auto_now_add=True)


class Shipment(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
    orderId = models.CharField(max_length=100)
    products = models.ManyToManyField(Product)
    orderDate = models.CharField(max_length=100)
    address = models.CharField(max_length=200)
    phoneNumber = models.CharField(max_length=13)

I just removed additional functions i.e. __str__ and others.

Here is the views.py

def orderSuccessful(request):
    number = Customer.objects.filter(user=request.user).values('phoneNumber')
    fullAddress = Customer.objects.filter(user=request.user).values('address')
    timeIn = time.time() * 1000  # convert current time in milliSecond
    if request.method == 'POST':
        order = Shipment.objects.create(customer=request.user.customer, orderId=timeIn,
                                        orderDate=datetime.datetime.now(), address=fullAddress,
                                        phoneNumber=number)
        user = Customer.objects.get(user=request.user)
        preOrder = Order.objects.filter(customer=user)
        orders = Order.objects.get(customer=request.user.customer, orderCompleted=False)
        items = orders.cart_set.all()  # Here is all the items of cart
        for product in items:
            product = Product.objects.filter(productId=items.product.productId)  # error is on this line
            order.products.add(product)

        Cart.objects.filter(order=preOrder).delete()
        preOrder.delete()
        order.save()
    else:
        return HttpResponse("Problem in Placing the Order")
    context = {
        'shipment': Shipment.objects.get(customer=request.user.customer)
    }
    return render(request, "Amazon/order_success.html", context)

How to resolve this error and all the cart items to field products in Shipment model?

6
  • items = orders.cart_set.all() this is not all the items, it is a queryset of all Cart instances related to the orders instance Commented Feb 1, 2021 at 17:20
  • @AbdulAzizBarkat, then how can I insert a queryset into another? Commented Feb 1, 2021 at 17:27
  • Is your Order supposed to have only one cart? Commented Feb 1, 2021 at 17:31
  • @AbdulAzizBarkat Yes, It works like this user can have a single order at the current time with multiple products. Commented Feb 1, 2021 at 17:34
  • I'll confim can you change this line in the Cart model order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True) to order = models.OneToOneField(Order, on_delete=models.SET_NULL, blank=True, null=True)? Or is that different from your intention? Commented Feb 1, 2021 at 17:37

2 Answers 2

2

Your model is not really consistent at all. Your Cart object is an m:n (or m2m - ManyToMany) relationship between Product and Order. Usually, you would have a 1:n between Cart and Product (a cart contains one or more products). One Cart might be one Order (unless you would allow more than one carts per order). And a shipment is usually a 1:1 for an order. I do not see any of this relationships in your model.

Draw your model down and illustrate the relations between them first - asking yourself, if it should be a 1:1, 1:n or m:n? The latter can be realized with a "through" model which is necessary if you need attributes like quantities.

In this excample, we have one or more customers placing an order filling a cart with several products in different quantities. The order will also need a shipment fee.

By the way: bear in mind that "filter()" returns a list. If you are filtering on user, which is a one to one to a unique User instance, you would better use "get()" as it returns a single instance. Putting in into a try - except or using get_object_or_404() makes it more stable.

product = Product.objects.filter(productId=items.product.productId)

should be something like:

product = product.product

not to say, it becomes obsolete.

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer Friend! Really liked the fact that you explored on modelling.
1

It looks like you make a cart for a product by multiple instances of Cart, the problem is you try to access the wrong variable, also you don't need to filter again when you already have the instance, make the following changes:

carts = orders.cart_set.all()  # Renamed items to carts for clarity
for cart in carts:
    product = cart.product
    order.products.add(product) # The name order is very misleading makes one think it is an instance of Order, actually it is an instance of Shipment

As mentioned above in my comment your variable names are somewhat misleading, please give names that make sense to any variable.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.