finethen
finethen

Reputation: 433

Python, Django: Limit IntegerField inside models.py

I would like to ask, if it's possible to limit one IntegerField inside my model-class in comparison to another one!? For example:

models.py

class Example(models.Model):
    name = models.CharField(max_length=50, null=False, blank=False, unique=True)
    ports = models.IntegerField(default=1, validators=[MinValueValidator(1), MaxValueValidator(50)])
    ports_active = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(50)])

As you may see, the ports_active are related to ports!? Is it possible to limit the ports_active-field, so that it can only be less or equal, but never greater than ports?

Thanks for your help and have a great day!

Upvotes: 2

Views: 115

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476659

You can add a CheckConstraint [Django-doc] to your model to enforce this at the database side (if the database supports this), and furthermore you can override the .clean(…) method [Django-doc] to validate this at the Django/Python level:

from django.core.exceptions import ValidationError
from django.db.models import F, Q

class Example(models.Model):
    name = models.CharField(max_length=50, null=False, blank=False, unique=True)
    ports = models.IntegerField(
        default=1,
        validators=[MinValueValidator(1), MaxValueValidator(50)]
    )
    ports_active = models.IntegerField(
        default=0,
        validators=[MinValueValidator(0), MaxValueValidator(50)]
    )
    
    def clean(self):
        if self.ports_active > self.ports:
            raise ValidationError('ports active should be less than or equal to ports')
        return super().clean()
    
    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(ports__gte=F('ports_active')),
                name='ports_gte_to_ports_active'
            )
        ]

Upvotes: 4

Related Questions