In my ecommerce app when I click on add to cart the product goes to the cart but when I click on the cart it gives me the error that 'Field 'id' expected a number but got 'product_id''. Basically I use context_processor to pass the cart.py information to the template. Link to the cart from base.html is:
<div class="navbar-item">
<a href="{% url 'cart' %}" class="button is-dark">Cart {% if cart %}({{cart|length}}){% endif %}</a>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
When I click on cart this error is generated:
Field 'id' expected a number but got 'product_id'
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
my project/urls.py is
path('cart/',include("cart.urls")),
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
my cart/urls.py is
urlpatterns = [
path('',views.cart_detail, name='cart')
]
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
my cart/cart.py is
from django.conf import settings
from product.models import Product
class Cart(object):
def __init__(self, request):
self.session = request.session
cart = self.session.get(settings.CART_SESSION_ID)
if not cart:
cart = self.session[settings.CART_SESSION_ID] = {}
self.cart = cart
def __iter__(self):
for p in self.cart.keys():
self.cart[(p)]['product'] = Product.objects.get(pk=p)
for item in self.cart.values():
item['total_price'] = item['product'].price * item['quantity']
yield item
def __len__(self):
return sum(item['quantity'] for item in self.cart.values())
def add(self, product_id, quantity=1, update_quantity=False):
product_id = str(product_id)
if product_id not in self.cart:
self.cart[product_id] = {'quantity': 1, 'id': product_id}
if update_quantity:
self.cart[product_id]['quantity'] = int(quantity)
if self.cart[product_id]['quantity'] == 0:
self.remove(product_id)
self.save()
print(self.cart)
def remove(self, product_id):
if product_id in self.cart:
del self.cart[product_id]
self.save()
def save(self):
self.session[settings.CART_SESSION_ID] = self.cart
self.session.modified = True
def clear(self):
del self.session[settings.CART_SESSION_ID]
self.session.modified = True
def get_total_cost(self):
for p in self.cart.keys():
self.cart[str(p)]['product'] = Product.objects.get(pk=p)
return sum(item['quantity'] * item['product'].price for item in self.cart.values())
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
my context_processors.py is
def cart(request):
return {'cart': Cart(request)}
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
and my cart.html is:
{% extends 'core/base.html' %}
{% block title %}Cart | {% endblock %}
{% block content %}
<h1 class="title">Cart</h1>
{% if cart %}
<div class="box mb-6">
<div class="table">
<table class="table is-fullwidth is-striped">
<thead>
<th></th>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
<th></th>
</thead>
<tbody>
{% for item in cart %}
<tr>
<td>
<figure class="image is-64x64">
<img src="{{ item.product.get_thumbnail }}">
</figure>
</td>
<td>
<a href="{% url 'product' item.product.category.slug item.product.slug %}">{{ item.product.title }}</a>
</td>
<td>
{{ item.quantity }}
<a href="?change_quantity={{ item.id }}&quantity=-1">-</a>
<a href="?change_quantity={{ item.id }}&quantity=1"> </a>
</td>
<td>${{ item.total_price }}</td>
<td><a href="?remove_from_cart={{ item.id }}" class="delete">Remove</a></td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td></td>
<td><strong>Total cost</strong></td>
<td><strong>{{ cart|length}}</strong></td>
<td colspan="2"><strong>${{ cart.get_total_cost }}</strong></td>
</tr>
</tfoot>
</table>
</div>
</div>
<h2 class="subtitle">Contact information</h2>
<form method="post" action="." id="payment-form">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="notification is-danger">
{{ form.non_field_errors}}
</div>
{% endif %}
{% if form.errors %}
<div class="notification is-danger">
<ul>
{% for field in form %}
{% for error in field.errors %}
<li><strong>{{ field.label }}: </strong>{{ error }}</li>
{% endfor %}
{% endfor %}
</ul>
</div>
{% endif %}
<div class="columns">
<div class="column is-6">
<div class="field">
<label>First name</label>
<div class="control">
<input class="input" type="text" name="first_name">
</div>
</div>
<div class="field">
<label>Last name</label>
<div class="control">
<input class="input" type="text" name="last_name">
</div>
</div>
<div class="field">
<label>E-mail</label>
<div class="control">
<input class="input" type="email" name="email">
</div>
</div>
<div class="field">
<label>Phone</label>
<div class="control">
<input class="input" type="text" name="phone">
</div>
</div>
</div>
<div class="column is-6">
<div class="field">
<label>Address</label>
<div class="control">
<input class="input" type="text" name="address">
</div>
</div>
<div class="field">
<label>Zip code</label>
<div class="control">
<input class="input" type="text" name="zipcode">
</div>
</div>
<div class="field">
<label>Place</label>
<div class="control">
<input class="input" type="text" name="place">
</div>
</div>
</div>
</div>
</form>
<h2 class="subtitle">Payment information</h2>
<div id="card-element">
<!-- A Stripe Element will be inserted here -->
</div>
{% if messages %}
{% for message in messages %}
<div class="notification is-danger">{{ message }}</div>
{% endfor %}
{% endif %}
<div class="field">
<div class="control">
<button class="button is-dark mt-4 is-uppercase">Checkout</button>
</div>
</div>
</div>
{% else %}
<p>You don't have any products in your cart!</p>
{% endif %}
{% endblock %}
<iframe name="sif7" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Aren't you casting the product_id to a string with str(product_id)
? And later you're passing it as an number but it's still an string. In cart.py
and function add
CodePudding user response:
The answer is I did not clear cookies. As I clear those o the code
CodePudding user response:
change this:
{'quantity': 1, 'id': product_id}
with this
{'quantity': 1, 'id': int(product_id)}