Reputation: 61
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
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
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)
, whereobject
is the retrieved or created object andcreated
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