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)