How to add and substract item form a product model


(Nehat Khan) #1

I am creating a stock management system in Django but i am stuck with adding, subtracting and updating the quantity in the model. Suppose I add a product (x) , initially the quantity of the product is 0. How can add or subtract the quantity and update the model at the same time so that it shows actual quantity of stock in that product model.
Thanks in advance. Please help me out


(Vitor Freitas) #2

I would store this information in two places. One in your Product model itself, and the other would be a specific model to store all the log and all add/subtract operations.

Basically the stock quantity would be calculable by processing all transactions. But over the time this could start to take long and become impractical. That’s why you would have a “cached” quantity directly in the Product model.

Just an example:

class Product(models.Model):
    name = models.CharField(max_length=30)
    quantity = models.IntegerField(default=0)

class StockLog(models.Model):
    IN = 'I'
    OUT = 'O'
    OPERATIONS = (
        (IN, 'In'),
        (OUT, 'Out'),
    )

    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='stock_logs')
    date = models.DateTimeField()
    operation = models.CharField(max_length=1, choices=OPERATIONS)
    quantity = models.IntegerField(default=0)

So let’s stay you create a new product:

product = Product.objects.create(name='Computer A')

Then you want to add 10 to stock:

from django.db import transaction
from django.db.models import F
from django.utils import timezone

with transaction.atomic():
    Product.objects.filter(id=product.pk).update(quantity=F('quantity') + 10)
    StockLog.objects.create(
        product=product, 
        date=timezone.now(), 
        operation=StockLog.IN, 
        quantity=10
    )

Note that I’m using a single database transaction to modify the Product and the StockLog models. That’s because we want to keep the integrity of the data flawless.

The F() expression is for the same reason. It will guarantee that we are increasing 10 in the stock based on the most up to date information on our database. Read more about the F() expressions here: Using F() Expressions

Now let’s say you made on sale, so you want to decrease your stock in 1:

with transaction.atomic():
    Product.objects.filter(id=product.pk).update(quantity=F('quantity') - 1)
    StockLog.objects.create(
        product=product, 
        date=timezone.now(), 
        operation=StockLog.OUT, 
        quantity=1
    )

You have to make sure Product and StockLog are always in sync.

This is a basic stock management, but should be enough to get you started


(Nehat Khan) #3

Sir it would be very helpful if you make a video or share any tutorial where I can understand the full concept as I am begineer. I understand a lot from this but by looking at your video guide it will get cleared. Thank You sir!


(Nehat Khan) #4

Do i have to create to view function i.e one for adding in stock and one for deleting from stock. I want to create a form so that user can input the to delete or add. How can i achieve that. And i am a begineer so messed up


(Vitor Freitas) #5

It can be one form to create StockLog instances. In this form the user would select from a radio button if the operation would be to add to the stock or to remove.

But how the product would be removed from the stock depends on what your application is doing. If it is for a store, the remove operation would happen when the purchase order is created, or when the sales person make a sale and update the system, etc.

In a real scenario you may also want to have a “reason” field or something, to keep track of why the item is being removed from the stock (sales, returned to vendor, gift, broken, etc)


(Nehat Khan) #6

Let me tell you the whole idea of the project! I got a warehouse in which we stock the profucts and for sell we take out too. Now i just keep track the stock/ quantity of the product that i have in my warehouse and when keep track of every transaction that i store and removed from the warehouse. I just want that functionality.