简体   繁体   中英

Auto update model value based on another value in this model django

I have a model called Products. This model has values like this

class Product(models.Model):
    title       = models.CharField(max_length=70, null=True, blank=True)
    producent   = models.CharField(max_length=40, null=True, blank=True)
    stock       = models.PositiveIntegerField(default=0, null=True, blank=True)
    display     = models.BooleanField(null=True, blank=True, default=True)

How can I change display to be False if stock is equal to 0 automatically, so when client buys last product in store display value will change from True to False and

Product.objects.filter(display=True)

will result in products that I want to show or are in stock.

I know that I can simply chain.filter() but I wonder if I can do in an elegant way

For what you said I think you have a view to decrease stock value

Add this logic to your view, after update the stock value:

if product.stock==0:
    product.display = False
    product.save()

Considering that your view (used to decrease stock value) already instantiated the target "product". If that don't help you, please, post your view.py, to give us more information.

I would leave the display field: adding logic to set that field will make the server more complicated, and it also means that if later stock is available again, someone has to manually set display back to True , since you can not know if display was set to False because you do not want to display the item, or because there was no stock.

You can filter with:

Product.objects.filter(display=True, stock__gt=0)

Since you probably want to that nearly every time you access objects, you can override the objects mananger with a custom manager [Django-doc] :

class ProductManager(models.Manager):
    def get_querset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            display=True, stock__gt=0
        )

class Product(models.Model):
    # …
    objects = ProductManager()

If you now use Product.objects.all() for example, it will automatically filter the Product items. If you need all the Product s, you can work with Product._base_manager.all() .

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