Home > other >  cannot unpack non-iterable int object creating shop and cart in Django with session
cannot unpack non-iterable int object creating shop and cart in Django with session

Time:05-09

I am creating a store and when executing this address http://127.0.0.1:8000/carro/agregar/3/ it has to load the product in the store widget where the cart is. If the car is not in the session, create it. Tried deleting cookies and nothing. But when I press the buy button on any product, in this case on product 3, the button sends to the correct address but the page gives me the following error

TypeError at /carro/agregar/3/ cannot unpack non-iterable int object Request Method: GET Request URL: http://127.0.0.1:8000/carro/agregar/3/ Django Version: 4.0.4 Exception Type: TypeError Exception Value: cannot unpack non-iterable int object Exception Location: C:\Users\HP\AppData\Local\Programs\Python\Python310\lib\site-packages\django\db\models\sql\query.py, line 1374, in build_filter Python Executable: C:\Users\HP\AppData\Local\Programs\Python\Python310\python.exe Python Version: 3.10.4

and this

C:\Users\HP\Documents\ProyectosDjango\ProyectoWeb\carro\views.py, line 8, in agregar_producto

producto = Producto.objects.get(producto_id)

views.py

from django.shortcuts import redirect
from .carro import Carro
from tienda.models import Producto

# Create your views here.
def agregar_producto(request, producto_id):
    carro= Carro(request)
    producto = Producto.objects.get(producto_id)
    carro.agregar(producto=producto)
    return redirect('Tienda')

def eliminar_producto(request, producto_id):
    carro= Carro(request)
    producto = Producto.objects.get(producto_id)
    carro.eliminar(producto=producto)
    return redirect('Tienda')

def restar_producto(request, producto_id):
    carro= Carro(request)
    producto = Producto.objects.get(producto_id)
    carro.restar(producto=producto)
    return redirect('Tienda')

def limpiar_carro(request):
    carro= Carro(request)
    carro.limpiar_carro()
    return redirect('Tienda')

context_processor.py

def importe_total_carro(request):
    total = 0
    if request.user.is_authenticated:
        for key, value in request.session["carro"].items():
            

            total = total  (float(value['precio'])*value['cantidad'])
    return {'importe_total_carro':total}

urls.py

    from django.urls import path
from . import views
app_name= "carro"
urlpatterns = [  
    path('agregar/<int:producto_id>/', views.agregar_producto, name="agregar"),  
    path('eliminar/<int:producto_id>/', views.eliminar_producto, name="eliminar"),  
    path('restar/<int:producto_id>/', views.restar_producto, name="restar"),  
    path('limpiar/>', views.limpiar_carro, name="limpiar"),  
]

carro.py (classes)

class Carro:
    def __init__(self,request):
        self.request=request
        self.session=request.session
        carro = self.session.get("carro")
        if not carro:
            carro=self.session["carro"]={}
            self.session.modified = True
        #else:
        self.carro = carro
    def agregar(self, producto):
        print('Estos son los datos {} => {}'.format(self, producto))
        if (str(producto.id) not in self.carro.keys()):
            self.carro[producto.id]={
                "producto.id":producto.id,
                "nombre":producto.nombre,
                "precio":str(producto.precio),
                "cantidad":1,
                "imagen":producto.imagen.url
            }
        else:
            for key, value in self.carro.items():
                if key == str(producto.id):
                    value["cantidad"] =  value["cantidad"]  1
                    break
        self.guardar_carro()
    
    def guardar_carro(self):
        self.session["carro"] = self.carro
        self.session.modified = True
    
    def eliminar(self, producto):
        producto.id= str(producto.id)
        if producto.id in self.carro.keys():
            del self.carro[producto.id]
            self.guardar_carro()

    def restar_producto(self,producto):
        for key, value in self.carro.items():
            if key == str(producto.id):
                value["cantidad"] =  value["cantidad"] - 1
                if value["cantidad"] < 1:
                    self.eliminar(producto)
                break
            self.guardar_carro()

    def limpiar_carro(self):
        self.session["carro"]={}
        self.session.modified = True

tienda.html

{% extends "ProyectoWebApp/base.html" %}
{% load static %}
{% block content %}
<div >
  <div style="float:right; margin-left: 10px;">
    
    {% include "carro/widget.html" %}
  </div>
  <div >
  {% for Prod in productos %}
    <div  > <!--style="padding: 10px; -->
      <div  style="width: 15rem;margin: 5px 5px;"> <!--style="padding: 10px; -->
        <img  src="{{Prod.imagen.url}}" height="160px" alt="Card image cap">
        <div >
          <h5 >{{Prod.nombre}}</h5>
          <p >{{Prod.precio}}</p>
          <a href="{% url 'carro:agregar' Prod.id %}" >comprar</a>
        </div>
      </div>
    </div>
  {% endfor %}
</div>
</div>

{% endblock %}

widget carrito

<table  style="color:white">
<thead>
    <tr>
        <th colspan="3" >
            Carro compras
        </th>

    </tr>
    <tr>
        <th>Producto</th>
        <th>Cantidad</th>
        <th>Suma</th>

    </tr>


</thead>
<tbody>
    {% if request.session.carro.items %}
        {% for key,value in request.session.carro.items %}
            <tr >
                <td>{{value.nombre}}</td>
                <td>{{value.cantidad}}</td>
                <td>
                    <a href="{% url 'carro:agregar' value.producto_id %}" > </a>
                    <a href="{% url 'carro:restar' value.producto_id %}" >-</a><br>
                    $ {{value.precio}} 
                </td>
            </tr>
        {% endfor %}
    {% else %}
    <tr>
        <td colspan="3">
            <div  >Carro Vacio</div>
        </td>
    </tr>

    {% endif %}
</tbody>
<tfoot>
    <tr>
        <td colspan="3">
            > Total: {{importe_total_carro}}

        </td>
    </tr>
</tfoot>

models.py

from http.client import PRECONDITION_FAILED
from django.db import models

# Create your models here.

class CategoriaProd(models.Model):
    nombre = models.CharField(max_length=50)
    created  = models.DateTimeField(auto_now_add=True)
    updated  = models.DateTimeField(auto_now_add=True)
    class Meta:
        verbose_name = 'categoriaProd'
        verbose_name_plural= 'categoriasProd'
    def __str__(self):
        return self.nombre
    
class Producto(models.Model):
    nombre = models.CharField(max_length=50)
    precio = models.FloatField()
    imagen =models.ImageField(upload_to='tienda', null=True, blank=True)
    categorias = models.ForeignKey(CategoriaProd, on_delete=models.CASCADE)
    disponibilidad = models.BooleanField(default=True)
    created  = models.DateTimeField(auto_now_add=True)
    updated  = models.DateTimeField(auto_now_add=True)
    class Meta:
        verbose_name = 'producto'
        verbose_name_plural= 'productos'
    def __str__(self):
        return self.nombre

CodePudding user response:

You can't just pass a single integer positional argument to the get or filter functions, you need to pass keyword arguments where the key is the name of the field you want to filter on.

If you are passing the id of the instance then use "id" as your keyword argument

producto = Producto.objects.get(id=producto_id)
  • Related