代码之家  ›  专栏  ›  技术社区  ›  Mike1982

字段“id”需要一个数字,但得到(字符串)

  •  0
  • Mike1982  · 技术社区  · 4 年前

    我正在创建一家有各种颜色的T恤店。在添加到购物车时,我遇到了以下错误: 字段“id”需要一个数字,但得到了“woodstock”。Woodstock是这件衬衫的名字,但我正在将cartid传递给函数。cartid实际上是在remove_from_cart函数中使用的,但是我不确定当我将add推到cart时为什么会抛出错误。 这是购物车模型:

    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

    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'),
    
    ]
    

    研究这个问题的一个建议是删除迁移并运行makemigrations/migrate,但这对我不起作用。是否有其他建议,或者item.id传递名称而不是id的原因?

    1 回复  |  直到 4 年前
        1
  •  2
  •   Iain Shelvington    4 年前

    你的 remove_from_cart url路径与以下路径匹配: cart/<id>/ 哪里 id 没有与任何内容匹配的类型 add_to_cart 路径使用 cart/<slug:slug>/ 但因为任何鼻涕虫也会匹配 身份证件 从前面的路径中,将永远使用此视图。您需要使这些路径唯一,以便它们永远不会匹配相同的路径。

    一种方法是 身份证件 一个整数,使slug与之不匹配

    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'),