【问题标题】:ValueError at /cart/add/3 "<Cart: None>" needs to have a value for field "id" before this many-to-many relationship can be used/cart/add/3 "<Cart: None>" 处的 ValueError 需要为字段 "id" 设置一个值,然后才能使用这种多对多关系
【发布时间】:2019-08-31 22:21:00
【问题描述】:

我正在尝试为我的电子商务网站制作 acart 组件 出现这个错误:ValueError at /cart/delete/2 "" 需要为字段 "id" 设置一个值,然后才能使用这种多对多关系。

views.py

from django.shortcuts import render, redirect, reverse
from django.urls import reverse_lazy
from .models import Cart
from products.models import Product
from django.shortcuts import get_object_or_404
def cart_home(request):
    cart_obj, new_obj=Cart.objects.new_or_get(request) 
    return render(request, "carts/home.html", {"cart":cart_obj})

def addproduct(request, id):
    productobj= get_object_or_404(Product, id=id)

    shoppingcart=Cart()

    shoppingcart.products.add(productobj)
    shoppingcart.save()
    return redirect("carts:home")
def removeproduct(request, id):
    productobj= get_object_or_404(Product, id=id)
    shoppingcart=Cart()
    shoppingcart.products.remove(productobj)
    shoppingcart.save()
    return redirect("carts:home")

'''' 模型.py ''''

from django.db import models
from django.conf import settings
from products.models import Product
from django.db.models.signals import pre_save, post_save, m2m_changed


User = settings.AUTH_USER_MODEL
class CartManager(models.Manager):
    def new_or_get(self, request):
        cart_id = request.session.get("cart_id", None)
        qs      = self.get_queryset().filter(id=cart_id)
        if qs.count() == 1:
            new_obj = False
            print('cart id exists')
            cart_obj = qs.first()
            if request.user.is_authenticated and cart_obj.user is None:
                cart_obj.user = request.user
                cart_obj.save()
        else:
            print("new cart created")
            new_obj = True
            cart_obj= Cart.objects.new(user=request.user)
            request.session['cart_id'] = cart_obj.id
        return cart_obj, new_obj

    def new(self, user=None):
        user_obj = None
        if user is not None:
            if user.is_authenticated:
                user_obj = user_obj
        return self.model.objects.create(user=user_obj)
class Cart(models.Model):

    user        = models.ForeignKey(User, null=True, blank=True, on_delete="Cascade")
    products    = models.ManyToManyField(Product, blank=True, null=True)
    total       = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
    updated     = models.DateTimeField(auto_now=True)
    timestamp   = models.DateTimeField(auto_now_add=True)

    objects = CartManager()

    def __str__(self):
        return str(self.id)
def m2m_changed_cart_receiver(sender, instance, *args, **kwargs):
    products = instance.products.all()
    total=0
    for x in products:
        total += x.price
    print(total)
    instance.total = total
m2m_changed.connect(m2m_changed_cart_receiver, sender=Cart.products.through)

'''' 购物车:home.html ''''

{% extends "base.html" %}
{% block content%}
<h1>Cart</h1>
{% if cart.products.exists %}

            <table class="table">
          <thead>
            <tr>
              <th scope="col">#</th>
              <th scope="col">Product Name</th>
              <th scope="col">Product Price</th>

            </tr>
          </thead>
          <tbody>
            {% for product in cart.products.all %}

            <tr>
              <th scope="row">{{forloop.counter}}</th>
              <td><a href="{{product.get_absolute_url}}">{{product.title}}</a>{% include "products/update_cart.html" %}</td>
              <td>{{product.price}}</td>

            </tr>
            {% endfor %}
            <tr>
              <th colspan="2"></th>

              <th><b>Total:</b>{{cart.total}}</th>
            </tr>

          </tbody>
        </table>
{% else %}
    <div class="lead"> Cart is empty</div>
{% endif %}


{% endblock %}

'''' 购物车更新.html

''''

{% if product in cart.products.all %}
    <form action="{% url 'carts:remove' product.id %}" 
                    method="post" style="display: inline;" onsubmit="window.mytest()">
                    {% csrf_token %}
                    <input type="hidden" name="product_id" 
                        value="{{ product.id }}" />
                    <button type="submit" class="btn btn-default btn-sm">
                        <span class="fas fa-trash-alt"></span>remove?
                    </button>
            </form> 
  {% else %}
            <form action="{% url 'carts:add' product.id %}" 
                    method="post" style="display: inline;" onsubmit="window.mytest()">
                    {% csrf_token %}
                    <input type="hidden" name="product_id" 
                        value="{{ product.id }}" />
                    <button type="submit" class="btn btn-default btn-sm">
                        <span class="fas fa-trash-alt"></span>add to cart
                    </button>
            </form> 
{% endif %}

'''' 所以在产品:详细信息模板中有一个按钮使我可以将此产品添加到购物车或删除(如果有) 如何解决上述错误以及如何使按钮转到确定的视图?提前感谢>>>

【问题讨论】:

  • 请提供完整的回溯。我假设这与保存之前正在使用的对象有关,这意味着它还没有时间生成其 ID。
  • ValueError at /cart/delete/2 "" 需要为字段“id”设置一个值,然后才能使用这种多对多关系。请求方法:POST 请求 URL:127.0.0.1:8000/cart/delete/2 Django 版本:2.1.5 异常类型:ValueError 异常值:“”需要字段“id”的值才能建立这种多对多关系用过的。异常位置:/home/zynaboo/Desktop/dev/ecommerce/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py in init,第 823 行 Python 可执行文件: /home/zynaboo/Desktop/dev/ecommerce/bin/python

标签: django many-to-many cart valueerror


【解决方案1】:

cart_home 中,您正确使用Cart.objects.new_or_get 来获取或创建购物车。但在其他视图中,您只需使用Cart();这只是实例化了一个新的未保存的购物车,因此出现了错误。你也需要在那里使用new_or_get

【讨论】:

  • 如果我不需要使用 new_or_get 函数怎么办 >> 我需要删除它没有这个函数我该如何处理?
  • 我不明白你的问题。这些视图都不是用于删除购物车。如果你想删除一个购物车,你可能需要一种方法,它只执行“获取”部分,如果没有找到则不创建新的。
  • 是的,你是对的,所以在尝试解决以下问题时:
【解决方案2】:
def cart_home(request):
    cart_obj, new_obj=Cart.objects.new_or_get(request) 
    return render(request, "carts/home.html", {"cart":cart_obj})

def addproduct(request, id):
    productobj= get_object_or_404(Product, id=id)

    shoppingcart=Cart.objects.new_or_get(request)

    shoppingcart.products.add(productobj)
    shoppingcart.save()
    return redirect("carts:home")
def removeproduct(request, id):
    productobj= get_object_or_404(Product, id=id)
    shoppingcart=Cart.objects.new_or_get(request)
    shoppingcart.products.remove(productobj)
    shoppingcart.save()
    return redirect("carts:home")

出现此错误: /cart/delete/1 处的 AttributeError “元组”对象没有属性“产品” 请求方法:POST 请求网址:http://127.0.0.1:8000/cart/delete/1 Django 版本:2.1.5 异常类型:属性错误 异常值:
“元组”对象没有属性“产品” 异常位置:/home/zynaboo/Desktop/dev/ecommerce/src/carts/views.py 在 removeproduct,第 26 行 Python 可执行文件:/home/zynaboo/Desktop/dev/ecommerce/bin/python Python版本:3.6.7 Python 路径:
['/home/zynaboo/Desktop/dev/ecommerce/src', '/home/zynaboo/Desktop/dev/ecommerce/lib/python36.zip', '/home/zynaboo/Desktop/dev/ecommerce/lib/python3.6', '/home/zynaboo/Desktop/dev/ecommerce/lib/python3.6/lib-dynload', '/usr/lib/python3.6', '/home/zynaboo/Desktop/dev/ecommerce/lib/python3.6/site-packages'] 服务器时间:2019年4月10日星期三13:26:56 +0000

【讨论】:

  • new_or_get 返回一个 cart, new 的元组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 2020-08-08
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多