无法使用会话在 Django 中解包不可迭代的 int 对象创建商店和购物车
cannot unpack non-iterable int object creating shop and cart in Django with session
我正在创建一个商店,当执行这个地址时 http://127.0.0.1:8000/carro/agregar/3/ 它必须将产品加载到购物车所在的商店小部件中。如果汽车不在会话中,请创建它。尝试删除 cookie,但什么也没有。但是当我按下任何产品上的购买按钮时,在本例中是产品 3,按钮发送到正确的地址但页面给我以下错误
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
还有这个
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 (类)
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 class="container">
<div style="float:right; margin-left: 10px;">
{% include "carro/widget.html" %}
</div>
<div class="row ">
{% for Prod in productos %}
<div class="col-sm-4" > <!--style="padding: 10px; -->
<div class="card" style="width: 15rem;margin: 5px 5px;"> <!--style="padding: 10px; -->
<img class="card-img-top" src="{{Prod.imagen.url}}" height="160px" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{Prod.nombre}}</h5>
<p class="card-text">{{Prod.precio}}</p>
<a href="{% url 'carro:agregar' Prod.id %}" class="btn btn-primary">comprar</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
小工具卡里托
<table class="table table-bordered" style="color:white">
<thead>
<tr>
<th colspan="3" class="tex-center">
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 class="text-center">
<td>{{value.nombre}}</td>
<td>{{value.cantidad}}</td>
<td>
<a href="{% url 'carro:agregar' value.producto_id %}" class="btn btn-sm btn-succes">+</a>
<a href="{% url 'carro:restar' value.producto_id %}" class="btn btn-sm btn-danger">-</a><br>
$ {{value.precio}}
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="3">
<div class="alert alert-danger text=center" >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
您不能只将单个整数位置参数传递给 get
或 filter
函数,您需要传递关键字参数,其中键是您要过滤的字段的名称上。
如果要传递实例的 id
,则使用“id”作为关键字参数
producto = Producto.objects.get(id=producto_id)
我正在创建一个商店,当执行这个地址时 http://127.0.0.1:8000/carro/agregar/3/ 它必须将产品加载到购物车所在的商店小部件中。如果汽车不在会话中,请创建它。尝试删除 cookie,但什么也没有。但是当我按下任何产品上的购买按钮时,在本例中是产品 3,按钮发送到正确的地址但页面给我以下错误
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
还有这个
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 (类)
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 class="container">
<div style="float:right; margin-left: 10px;">
{% include "carro/widget.html" %}
</div>
<div class="row ">
{% for Prod in productos %}
<div class="col-sm-4" > <!--style="padding: 10px; -->
<div class="card" style="width: 15rem;margin: 5px 5px;"> <!--style="padding: 10px; -->
<img class="card-img-top" src="{{Prod.imagen.url}}" height="160px" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{Prod.nombre}}</h5>
<p class="card-text">{{Prod.precio}}</p>
<a href="{% url 'carro:agregar' Prod.id %}" class="btn btn-primary">comprar</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
小工具卡里托
<table class="table table-bordered" style="color:white">
<thead>
<tr>
<th colspan="3" class="tex-center">
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 class="text-center">
<td>{{value.nombre}}</td>
<td>{{value.cantidad}}</td>
<td>
<a href="{% url 'carro:agregar' value.producto_id %}" class="btn btn-sm btn-succes">+</a>
<a href="{% url 'carro:restar' value.producto_id %}" class="btn btn-sm btn-danger">-</a><br>
$ {{value.precio}}
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="3">
<div class="alert alert-danger text=center" >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
您不能只将单个整数位置参数传递给 get
或 filter
函数,您需要传递关键字参数,其中键是您要过滤的字段的名称上。
如果要传递实例的 id
,则使用“id”作为关键字参数
producto = Producto.objects.get(id=producto_id)