JEA
JEA

Reputation: 75

AttributeError: 'QuerySet' object has no attribute 'product' ERROR

Hi I'm building a Webshop with a cart and checkout function. Now I'm trying to add the products and their quantity to an Email form which I want to send to an email obviously but I don't know how I could get the item.name or the item.quantity without getting an error as shown below.

I have the following models:

class Customer(models.Model):
    user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200)

    def __str__(self):
        return self.name


class Product(models.Model):
    name = models.CharField(max_length=200, null=True)
    price = models.FloatField()
    digital = models.BooleanField(default=False, null=True, blank=False)  # Nicht nötig
    image = models.ImageField(null=True, blank=True)

    def __str__(self):
        return self.name

    @property
    def imageURL(self):
        try:
            url = self.image.url
        except:
            url = ''
        return url


class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
    date_ordered = models.DateTimeField(auto_now_add=True)
    complete = models.BooleanField(default=False, null=True, blank=False)
    transaction_id = models.CharField(max_length=200, null=True)

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

    @property
    def get_cart_total(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.get_total for item in orderitems])
        return total

    @property
    def get_cart_items(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.quantity for item in orderitems])
        return total



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

    @property
    def get_total(self):
        total = self.product.price * self.quantity
        return total

So I'm trying to get the product name and quantity from an Query set. But I get an error as described in the title

AttributeError: 'QuerySet' object has no attribute 'product'.

I'm trying to append the product name and quantity a customer has selected to a message variable which will be send to an email with sendmail().

This is my view:

@login_required(login_url='login')
def checkout(request):
    if request.method == "POST":
        message_name = request.POST['message-name']
        message_email = request.POST['message-email']
        message = request.POST['message']
        message_to_send = str(message)
        # send an email
        send_mail(
             'message from ' + message_name,  # subject
             message_to_send,  # message
             message_email,  # from email
             ['[email protected]'],  # To Email
        )
    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer=customer, complete=False)
        items = order.orderitem_set.all()
        cartItems = order.get_cart_items
        print(items.product.name)
        print(items.quantity)

    context = {'items': items, 'order': order, 'cartItems': cartItems}
    return render(request, 'store/checkout.html', context)

Thank you for any help.

Upvotes: 1

Views: 1402

Answers (1)

Shyrtle
Shyrtle

Reputation: 647

You are calling items.product.name in your print statement, but items is a set of objects not just a single object.

You can fix this by using the following code in your views.py in place of print(items.product.name)

for item in items:
    print(item.product.name)

You can also reference this directly in your template, by using the {% for %} code.

Example:

Inside your template.html

{% for item in items %}
    <h1>{{item.product.name}}</h1>
{% endfor %}

Upvotes: 2

Related Questions