Home > OS >  Field 'id' expected a number but got 'product_id' django
Field 'id' expected a number but got 'product_id' django

Time:11-05

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)}
  • Related