Vinney
Vinney

Reputation: 61

int() argument must be a string, a bytes-like object or a number, not 'OrderItem'? Django

I am creating an E-commerce now when I try adding an Item into the cart it returns the error above?

It is complaining about this line of code in the view:

else:
   order.items.add(order_item)

View

def add_to_cart(request, slug):
   item = get_object_or_404(Item, slug=slug)
   order_item = OrderItem.objects.get_or_create(
       item=item,
       user = request.user,
       ordered = False
   )
   order_qs = Order.objects.filter(user=request.user, ordered=False)
   if order_qs.exists():
       order = order_qs[0]
       #check if the order item is in the order
       if order.items.filter(item__slug=item.slug).exists():
           order_item.quantity += 1
           order_item.save()
       else:
           order.items.add(order_item)
   else:
       ordered_date = timezone.now()
       order = Order.objects.create(user=request.user, ordered_date=ordered_date)
       order.items.add(order_item)
   return redirect("core:product", slug=slug)

Model

class OrderItem(models.Model):
   user = models.ForeignKey(settings.AUTH_USER_MODEL,    on_delete=models.CASCADE)    
   ordered = models.BooleanField(default=False)
   item = models.ForeignKey(Item, on_delete=models.CASCADE)
   quantity = models.IntegerField(default=1) 



   def __str__(self):
       return f"{self.quantity} of {self.item.title}"

class Order(models.Model):
   user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
   items = models.ManyToManyField(OrderItem)
   start_date = models.DateTimeField(auto_now_add= True)
   ordered_date = models.DateTimeField()
   ordered = models.BooleanField(default=False)

   def __str__(self):
       return self.user.username

Traceback

Internal Server Error: /add-to-cart/pants-2/
Traceback (most recent call last):
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/core/views.py", line 38, in add_to_cart
    order.items.add(order_item)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 965, in add
    through_defaults=through_defaults,
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 1092, in _add_items
    '%s__in' % target_field_name: new_ids,
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/query.py", line 892, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/query.py", line 910, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1290, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1318, in _add_q
    split_subq=split_subq, simple_col=simple_col,
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1251, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1116, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/lookups.py", line 20, in __init__
    self.rhs = self.get_prep_lookup()
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in get_prep_lookup
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 59, in <listcomp>
    self.rhs = [target_field.get_prep_value(v) for v in self.rhs]
  File "/home/vince/Desktop/Dev-Projects/djangoEcommerce/django_project_boilerplate/env/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 966, in get_prep_value
    return int(value)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'OrderItem'
[24/Jun/2019 20:49:06] "GET /add-to-cart/pants-2/ HTTP/1.1" 500 150701


I need it to create a new item into the cart if it doesn't exist and if it exists inside the cart it increments the similar item by 1, instead of creating the same thing all over again.

Upvotes: 3

Views: 263

Answers (2)

Muhammed Mahir
Muhammed Mahir

Reputation: 178

add the below line into this. Just add 'created' as below.

 order_item, created = OrderItem.objects.get_or_create(
       item=item,
       user = request.user,
       ordered = False
   )

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477160

The Django get_or_create(..) [Django-doc], does not return a model instance, it returns a 2-tuple with the object, and a boolean (whether it created a record or not). Or as written in the documentation:

(..)

Returns a tuple of (object, created), where object is the retrieved or created object and created is a boolean specifying whether a new object was created.

(..)

You can easily fix this by using iterable unpacking however:

def add_to_cart(request, slug):
   item = get_object_or_404(Item, slug=slug)
   order_item, __ = OrderItem.objects.get_or_create(
       item=item,
       user = request.user,
       ordered = False
   )
   order_qs = Order.objects.filter(user=request.user, ordered=False)
   if order_qs.exists():
       order = order_qs[0]
       #check if the order item is in the order
       if order.items.filter(item__slug=item.slug).exists():
           order_item.quantity += 1
           order_item.save()
       else:
           order.items.add(order_item)
   else:
       ordered_date = timezone.now()
       order = Order.objects.create(user=request.user, ordered_date=ordered_date)
       order.items.add(order_item)
   return redirect("core:product", slug=slug)

Here we thus assign the result of OrderItem.objects.get_or_create(..) to order_item, __, with __ a "throw away variable".

Upvotes: 1

Related Questions