我正在创建一个带有变体/颜色的t恤商店。在添加到购物车,我得到的错误:Field 'id'期待的是一个数字,但得到的是'woodstock'。伍德斯托克是衬衫的名字,但我要把卡片传递给函数。cartid实际上是在remove_from_cart函数中使用的,但我不确定为什么当我把add推到购物车时抛出错误。下面是购物车模型:
class Cart(models.Model):
#user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
total = models.DecimalField(max_digits=100, decimal_places=2, default=0.00)
timestamp = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
active = models.BooleanField(default=True)
def __str__(self):
return "Cart id: %s" %(self.id)
class CartItem(models.Model):
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, null=True, blank=True)
product = models.ForeignKey(Product,on_delete=models.CASCADE)
variations = models.ManyToManyField(Variation, blank=True)
quantity = models.IntegerField(default=1)
line_total = models.DecimalField(default=10.99, max_digits=100, decimal_places=2)
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
try:
return str(self.cart.id)
except:
return self.product.name
views.py
def view(request):
print("viewing cart")
try:
the_id = request.session['cart_id']
except:
the_id = None
if the_id:
cart = Cart.objects.get(id=the_id)
new_total = 0.00
for item in cart.cartitem_set.all():
line_total = float(item.product.price) * item.quantity
new_total += line_total
request.session['items_total'] = cart.cartitem_set.count()
cart.total = new_total
cart.save()
context = {"cart":cart}
else:
empty_message = "Your cart is empty, please keep shopping"
context = {"empty": True, "empty_message": empty_message}
template = "cart/view.html"
return render(request, template, context)
def add_to_cart(request, slug):
print("add_to_cart pressed")
request.session.set_expiry(100000000)
try:
the_id = request.session['cart_id']
except:
#create cart id
new_cart = Cart()
new_cart.save()
request.session['cart_id'] = new_cart.id
the_id = new_cart.id
cart = Cart.objects.get(id=the_id)
try:
product = Product.objects.get(slug=slug)
except Product.DoesNotExist:
pass
except:
pass
product_variations = []
if request.method == 'POST':
qty = request.POST['qty']
for item in request.POST:
key = item
val = request.POST[key]
try:
v = Variation.objects.get(product=product, category__iexact=key, title__iexact=val)
product_variations.append(v)
except:
pass
cart_item = CartItem.objects.create(cart=cart, product=product)
if len(product_variations) > 0:
cart_item.variations.add(*product_variations)
cart_item.quantity = qty
cart_item.save()
print("cart item added")
return HttpResponseRedirect(reverse("carts:cart"))
return HttpResponseRedirect(reverse("carts:cart"))
def remove_from_cart(request, id):
print(id) #this is showing the item name, the reason it's not working. Either traced back to html view or urls.py
try:
the_id = request.session['cart_id']
cart = Cart.objects.get(id=the_id)
except:
return HttpResponseRedirect(reverse("carts:cart"))
cartitem = CartItem.objects.get(id=id)#error is traced to this line
cartitem.cart = None
cartitem.save()
return HttpResponseRedirect(reverse("carts:cart"))
html
{% block content %}
<div class="col-sm-8 offset-sm-2">
{% if empty %}
<h1 style="text-align:center;">{{ empty_message }}</h1>
{% else %}
<table class="table">
<thead>
<th>Item</th>
<th>Price</th>
<th>Qty</th>
<th></th>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
<td>Total: {{ cart.total }}</td>
</tr>
</tfoot>
{% for item in cart.cartitem_set.all %}
<tr>
<td>{{ item.product }}
{% if item.variations.all %}
<ul>
{% for var in item.variations.all %}
<li> {{ var.category|capfirst }} : {{ var.title|capfirst }}</li>
{% endfor %}
</ul>
{% endif %}
</td>
<td>{{ item.product.price }}</td>
<td>{{ item.quantity }}</td>
<td><a href='{% url "carts:remove_from_cart" item.id %}'>Remove</a></td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
{% endblock %}
url .py for购物车
app_name='carts'
urlpatterns =[
path('cart/', views.view, name='cart'),
path('cart/<id>/', views.remove_from_cart, name='remove_from_cart'),
path('cart/<slug:slug>/', views.add_to_cart, name='add_to_cart'),
]
研究这个问题的一个建议是删除迁移并运行makemigration/migrate,但这对我不起作用。还有其他建议吗?Id传递的是名称而不是Id ?
您的remove_from_cart
url路径匹配cart/<id>/
这样的路径,其中id
没有类型,因此匹配任何内容,add_to_cart
路径使用cart/<slug:slug>/
,但因为任何段塞也将匹配id
从以前的路径,这个视图将永远使用。您需要使这些路径唯一,以便它们永远不会匹配相同的路径。
一种方法是将id
设置为整数,这样鼻涕虫就不会匹配它
path('cart/<int:id>/', views.remove_from_cart, name='remove_from_cart'),
path('cart/<slug:slug>/', views.add_to_cart, name='add_to_cart'),
更好的方法是为这些路径添加前缀,这样它们就不会冲突
path('cart/remove/<int:id>/', views.remove_from_cart, name='remove_from_cart'),
path('cart/add/<slug:slug>/', views.add_to_cart, name='add_to_cart'),