繁体   English   中英

Django 错误:/cart/ 处的 ValueError -> 必须使用切片将精确查找的 QuerySet 值限制为一个结果

[英]Django error: ValueError at /cart/ -> The QuerySet value for an exact lookup must be limited to one result using slicing

将书添加到购物车时出现价值错误。 它指向views.py中的for循环以获取订单。 我无法想办法解决它。 任何帮助表示赞赏。

bookstore-django/store/views.py”,第 68 行,在购物车中用于订单:

异常类型:/cart/ 处的 ValueError

异常值:精确查找的 QuerySet 值必须限制为使用切片的一个结果。

模型.py

from django.db import models
from django.db.models.query import prefetch_related_objects
from django.utils import timezone
from django.contrib.auth.models import User

class Author(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    def __str__(self):
        return "%s, %s" % (self.last_name, self.first_name)


class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, null=True, blank=True)
    description = models.TextField()
    publish_date = models.DateField(default=timezone.now)
    price = models.DecimalField(decimal_places=2, max_digits=8)
    stock = models.IntegerField(default=2)

    class Meta:
        verbose_name ='Book'
        verbose_name_plural = 'Books'
        db_table = 'book' #default is store_book


class Review(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    publish_date = models.DateField(default=timezone.now)
    text = models.TextField()


class Cart(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    active = models.BooleanField(default=True)
    order_date = models.DateField(null=True)
    payment_type = models.CharField(max_length=100, null=True)
    payment_id = models.CharField(max_length=100, null=True)

    def add_to_cart(self, book_id):
        book = Book.objects.get(pk=book_id)
        try:
            preexisting_order = BookOrder.objects.get(book=book, cart=self)
            preexisting_order.quantity += 1
            preexisting_order.save()
        except BookOrder.DoesNotExist:
            new_order = BookOrder.objects.create(
                book=book, 
                cart=self,
                quantity = 1
            )
            new_order.save

    def remove_from_cart(self, book_id):
        book = Book.objects.get(pk=book_id)
        try:
            preexisting_order = BookOrder.objects.get(book=book, cart=self)
            if preexisting_order.quantity > 1:
                preexisting_order.quantity -= 1
                preexisting_order.save()
            else: 
                preexisting_order.delete()
        except BookOrder.DoesNotExist:
            pass


class BookOrder(models.Model):
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)
    quantity = models.IntegerField()

视图.py

from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import redirect, render
from .models import Book, BookOrder, Cart
def index(request):

    context = {

    }
    return render(request, 'template.html', context)

def store(request):
    books = Book.objects.all()

    context = {
        'books': books,
    }

    return render(request, 'base.html', context)

def book_details(request, book_id):

    context = {
        'book': Book.objects.get(pk=book_id),
    }
    
    return render(request, 'store/detail.html', context)


def add_to_cart(request, book_id):
    if request.user.is_authenticated:
        try: 
            book = Book.objects.get(pk=book_id)
        except ObjectDoesNotExist:
            pass
        else:
            try:
                cart = Cart.objects.get(user=request.user, active=True)
            except ObjectDoesNotExist:
                cart = Cart.objects.create(
                    user=request.user
                )
                cart.save()
            cart.add_to_cart(book_id)
        return redirect('store:cart')
    else:
        return redirect('index')


def remove_from_cart(request, book_id):
    if request.user.is_authenticated:
        try:
            book = Book.objects.get(pk=book_id)
        except ObjectDoesNotExist:
            pass
        else:
            cart = Cart.objects.get(user=request.user, active=True)
            cart.remove_from_cart(book_id)
        return redirect('cart')
    else:
        return redirect('index')

def cart(request):
    if request.user.is_authenticated:
        cart = Cart.objects.filter(user=request.user.id, active=True)
        orders = BookOrder.objects.filter(cart=cart)
        total = 0
        count = 0
        
        for order in orders:
            total += (order.book.price * order.quantity)
            count += order.quantity
        
        context = {
            'cart': orders, 
            'total': total,
            'count': count,
        }
        return render(request, 'store/cart.html', context)
    else:
        return redirect('index')

网址.py

from django.urls import path
from . import views

app_name = 'store'

urlpatterns = [
    path('', views.index, name='index' ), 
    path('store/', views.store, name='store' ), 
    path('store/<int:book_id>', views.book_details, name='book_details'), 
    path('add/<int:book_id>', views.add_to_cart, name='add_to_cart'),    
    path('remove/<int:book_id>', views.remove_from_cart, name='remove_from_cart'), 
    path('cart/', views.cart, name='cart'),
]

购物车.html

{% block body %}
<div class="col-md-8 col-md-offset-2 col-sm-12 maincontent col-center">
    <div style="text-align:center;text-decoration:underline"><h3>Your Cart</h3></div>
        <div class="cart_container">
        {% for item in cart %}
            <div class="cart_item">
                <div class="cart_listing">
                    <span class="title">{{ item.book.title }}</span> by {{ item.book.author.first_name }} {{ item.book.author.last_name }}
                </div>
                <div class="cart_price">
                    <span class="cart_quantity">{{ item.quantity }} x $ <span class="cart_value">{{ item.book.price }}</span></span>

                    Quantity: <a href="{% url 'store:add_to_cart' book.id %}">[+]</a> / 
                    <a href="{ url 'store:remove_from_cart' item.book.id %}">[-]</a>
                </div>
            </div>
        {% empty %}
            <div>
            There are no items in your cart.
            </div>
        {% endfor %}
        <div class="cart_total">
             <h4> Total: $<span class="cart_value">{{ total }}</span></h4>
        </div>
        </div>
    </div>
</div>
{% endblock %}

底座.html

{% block body %}
                <div class="col-md-8 col-md-offset-2 col-sm-12 maincontent col-center" > 

                    <div style="text-align:center"><h3>Welcome to our store!</h3></div>

                    {% for book in books%}

                    <div class="storefront_book_display">
                    <a href="{% url 'store:book_details' book.id %}">
                            <img src="{% static 'base/img/empty_cover.jpg' %}">
                            <span class="storefront_book_title">{{ book.title }}</span>
                            <span class="storefront_book_author">{{ book.author }}</span>
                            </a>
                            <span class="storefront_add_to_cart">
                                <a href="{% url 'store:add_to_cart' book.id %}">Add to cart</a>
                            </span>
                    </div>
                    {% endfor %}                
                </div>
{% endblock %} 

你的问题在这里:

cart = Cart.objects.filter(user=request.user.id, active=True) # this is a queryset
orders = BookOrder.objects.filter(cart=cart) # this is the exact lookup mentioned

cart在这里是一个查询集,而不是一个实例。 如果您希望只有一个可能的购物车使用.get 如果有可能有多个结果,请像现在一样使用过滤器,但在订单查询中使用__in

将其更改为:

cart = Cart.objects.get(user=request.user.id, active=True)
orders = BookOrder.objects.filter(cart=cart)

或者

carts = Cart.objects.filter(user=request.user.id, active=True)
orders = BookOrder.objects.filter(cart__in=carts)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM