简体   繁体   中英

Django: How to reduce stock quantity when an order is made?

My goal is to reduce stock quantity when an order is created. My stock item is a Tyre. The tyre has a model field for quantity.

Here is my views.py

from django.shortcuts import render, redirect
from .models import OrderItem
from .forms import OrderCreateForm
from cart.cart import Cart
from stock.models import Tyre, Branch 
from django.contrib.auth.decorators import login_required


@login_required(login_url="/accounts/login/")
def order_create(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save()
            for item in cart:
                OrderItem.objects.create(
                    order=order,
                    tyre=item['tyre'],
                    price=item['price'],
                    quantity=item['quantity']
                )

                # reduce tyre stock quantity
                order_item = OrderItem.objects.get(id=id)
                tyre = Tyre.objects.get(id=id)
                tyre.quantity = tyre.quantity - order_item.quantity
                tyre.save()
           

            cart.clear()

            return redirect('orders:sale-orders')
        # return render(request, 'orders/sale_orders.html', {'order': order})
    else:
        form = OrderCreateForm()
    return render(request, 'orders/create_order.html', {'form': form})

When i run the code, I got this error: TypeError at /orders/create/ Field 'id' expected a number but got.

Here is my models.py for the orders app:

from django.db import models
from shop.models import Product

class Order(models.Model):
    customer_name = models.CharField(max_length=60)
    contact = models.CharField(max_length=12)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ('-created', )

    def __str__(self):
        return 'Order {}'.format(self.id)

    def get_total_cost(self):
        return sum(item.get_cost() for item in self.items.all())


class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
    tyre = models.ForeignKey(Tyre, related_name='order_items', on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveIntegerField(default=1)

    def __str__(self):
        return '{}'.format(self.id)

    def get_cost(self):
        return self.price * self.quantity

I appreciate any help

Looks like you are using python's inbuilt id function to perform the assignment to the id field of the OrderItem model. Something seems to be missing in your code. Where do you intend to get the value for the id kwarg in order_item = OrderItem.objects.get(id=id)

Not sure if this would work

from django.shortcuts import render, redirect
from .models import OrderItem
from .forms import OrderCreateForm
from cart.cart import Cart
from stock.models import Tyre, Branch 
from django.contrib.auth.decorators import login_required


@login_required(login_url="/accounts/login/")
def order_create(request):
    cart = Cart(request)
    if request.method == 'POST':
        form = OrderCreateForm(request.POST)
        if form.is_valid():
            order = form.save()
            for item in cart:
                order_item = OrderItem.objects.create(
                    order=order,
                    tyre=item['tyre'],
                    price=item['price'],
                    quantity=item['quantity']
                )

                # reduce tyre stock quantity
                tyre = Tyre.objects.get(id=item.id)

                # Not sure if item['tyre'] is an instance of tyre
                # other wise `tyre = item['tyre']` Could also work to replace
                # `tyre = Tyre.objects.get(id=item.id)`

                tyre.quantity = tyre.quantity - order_item.quantity
                tyre.save()
           

            cart.clear()

            return redirect('orders:sale-orders')
        # return render(request, 'orders/sale_orders.html', {'order': order})
    else:
        form = OrderCreateForm()
    return render(request, 'orders/create_order.html', {'form': form})

What Rogers stated above is very close. The line for getting tyre id tyre = Tyre.object.get(id=order_item.tyre.id) That solves everything.

Thanks Roger

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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