Почему я получаю ошибку "Cannot resolve keyword" в DJango при выполнении большой суммы?

Я разрабатываю сайт электронной коммерции, на котором только зарегистрированные пользователи могут делать заказы. Я хочу получить общую цену для всех заказов во время оформления заказа (т. е. order_price_total), но получаю ошибку:

Cannot resolve keyword 'order_price_total' into field. Choices are: delivered, id, order_date, paid, product, product_id, quantity, ready_for_delivery, shipped, user, user_id

Ниже приведена выдержка из моего кода (модель и представление):

class Product(models.Model):
    supplier = models.ForeignKey(Shop, on_delete=models.CASCADE)
    product_name = models.CharField(max_length=100, null=True, blank=True)
    brand_name = models.CharField(max_length=100, null=True, blank=True)
    image = models.FileField(upload_to='meadia/product-image', null=True)
    key_features = models.TextField(max_length=1000, null=True, blank=True)
    specifications = models.TextField(max_length=1000, null=True, blank=True)
    description = models.TextField(max_length=1000, null=True, blank=True)
    creation_date = models.DateTimeField(auto_now_add=True)
    
    def __str__(self):
        return self.product_name


class Order(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.DO_NOTHING)
    product = models.ForeignKey(Product, on_delete=models.DO_NOTHING)
    quantity = models.IntegerField(default=1, null=True, blank=True)
    order_date = models.DateTimeField(auto_now_add=True)
    
    paid = models.BooleanField(default=False)
    shipped = models.BooleanField(default=False)
    ready_for_delivery = models.BooleanField(default=False)
    delivered = models.BooleanField(default=False)

    def order_price_total(self):
        if self.paid == False:
            total_price = self.product.current_price * self.quantity
        return (total_price)
        
    def __str__(self):
        return self.product.product_name



##VIEW
@login_required(login_url='login')
def orders(request):
    order = Order.objects.filter(user=request.user)
    total_amount = Order.objects.filter(user=request.user, paid=False, delivered=False).aggregate(TOTAL = Sum('order_price_total'))['TOTAL'] or 0

    context={
            'order':order,
            'total_amount':total_amount,
        }
    return render(request, 'mainapp/cart.html', context)

Используйте тег Property
как указано ниже

class Order(models.Model):
        user = models.ForeignKey(CustomUser, on_delete=models.DO_NOTHING)
        product = models.ForeignKey(Product, on_delete=models.DO_NOTHING)
        quantity = models.IntegerField(default=1, null=True, blank=True)
        order_date = models.DateTimeField(auto_now_add=True)
    
    paid = models.BooleanField(default=False)
    shipped = models.BooleanField(default=False)
    ready_for_delivery = models.BooleanField(default=False)
    delivered = models.BooleanField(default=False)


    @property
    def order_price_total(self):
        if self.paid == False:
            total_price = self.product.current_price * self.quantity
        return (total_price)
        
    def __str__(self):
        return self.product.product_name

В шаблоне можно использовать order.order_price_total

Вы не можете работать с методом или свойством для агрегирования. Вы создаете элемент в виде запроса, поэтому:

from django.db.models import Case, F, When


@login_required(login_url='login')
def orders(request):
    order = Order.objects.filter(user=request.user)
    total_amount = (
        Order.objects.filter(
            user=request.user, paid=False, delivered=False
        ).aggregate(
            total=Sum(
                Case(
                    When(
                        paid=False,
                        then=F('product__current_price') * F('quantity'),
                    )
                )
            )
        )[
            'total'
        ]
        or 0
    )

    context = {
        'order': order,
        'total_amount': total_amount,
    }
    return render(request, 'mainapp/cart.html', context)

на основе Product модели, однако, не существует .current_price поля.

Я использовал annotate, и в моем случае это сработало всего в 1 строке кода.

Total_price = request.user.order_set.filter(paid=False, delivered=False).annotate(subtotal=F('quantity') * F('product_current_price)).aggregate(total_price=Sum('subtotal', output_field=FloatField()))['total_price'] or 0

Вернуться на верх