Home > Back-end >  Checking properties of an object based on separete view (Django|Django-Rest-Framework)
Checking properties of an object based on separete view (Django|Django-Rest-Framework)

Time:02-14

I am using django-rest-framework and React.js. I need a seperate function in the backend to check if CartItem.amount is lower then ProductStock.quantity, if CartItem.product equals ProductStock.id of course (this part does not work). For the same function I need to check if the pricing is the same as in Product model, but suprisingly this part of a function works. What can I do to make sure CartItem.amount will get lowered if it is higher than ProductStock.quantity?

Code below:

Product is a blueprint for the rest of the models.

ProductStock tracks the amount of different sizes of all of products.

CartItem is a model used for tracking how many products a user bought.

models.py

class Product(models.Model):
    name = models.CharField(max_length=150)
    price = models.IntegerField()
    slug = models.SlugField(blank=True, null=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(Product, self).save()

class ProductStock(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    size = models.CharField(max_length=6)
    quantity = models.IntegerField(default=0)

    def __str__(self):
        return f'{self.quantity} x {self.product.name}: {self.size}'

class CartItem(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
    product = models.ForeignKey(ProductStock, on_delete=models.CASCADE, blank=True, null=True)
    amount = models.IntegerField(default=0, blank=True, null=True)
    size = models.CharField(max_length=10, blank=True, null=True)
    price = models.IntegerField(blank=True, null=True)

    def __str__(self):
        return f'{self.user.email}, {self.product.product.name}, {self.product.size}: {self.amount}'
    
    def save(self, *args, **kwargs):
        if self.amount > self.product.quantity:
            self.amount = self.product.quantity
        self.size = self.product.size
        self.price = self.product.product.price
        super(CartItem, self).save()

views.py

def check_cart_content(request,user_id):
    cart = CartItem.objects.filter(user=user_id)

    for item in cart:
        product_stock = ProductStock.objects.filter(product=item.product.id)
        for stock in product_stock:
            if item.amount > stock.quantity:
                item.amount = stock.quantity

            product = Product.objects.get(id=item.product.id)
            if item.price != product.price:
                item.price = product.price

            item.save()

            return JsonResponse({'success': 'Cart checked'})

CodePudding user response:

You need to change indentation of JsonResponse cause it ends after first stock in product_stock. Also item.save() and more probably need indentation change. Revise that in clean Python.

def check_cart_content(request,user_id):
    cart = CartItem.objects.filter(user=user_id)

    for item in cart:
        product_stock = ProductStock.objects.filter(product=item.product.id)
        for stock in product_stock:
            if item.amount > stock.quantity:
                item.amount = stock.quantity

        product = Product.objects.get(id=item.product.id)
        if item.price != product.price:
            item.price = product.price

        item.save()

    return JsonResponse({'success': 'Cart checked'})

You should think of rebuilding model tree, cause ProductStock with ForeignKey seems bad solution. It would be better to count in function of Product, something similar to:

def quantity(self):
    return Product.objects.all().count()

because it works dynamically and you don't need extra objects in database.

  • Related