GaryOfNivea
GaryOfNivea

Reputation: 21

How do I use Django's CheckConstraint to restrict a variable at the database level?

I'm trying to write an application that receives incoming tickets for a small IT department. Currently these tickets come in through a webhook so I want to restrict what comes in at the database level. I want to restrict the status variable of the ticket to the choices described in the ticketStatus model but the database is still accepting values outside these choices. I've experimented with using CheckConstraint but can't quite get it to work.

My code is as follows:

class ticketStatus(models.TextChoices):
    Active = "Active"
    Acknowledged = "Acknowledged"
    Resolved = "Resolved"
    Unresolved = "Unresolved"


class Ticket(models.Model):

    dateTimeRecieved = models.DateTimeField(default=timezone.now)
    deviceId = models.ForeignKey(Device, related_name="Device", on_delete=models.DO_NOTHING)
    issue = models.CharField(max_length=100)
    status = models.CharField(max_length=20, default="Active")

    def __str__(self):
        return f"Device {self.deviceId}: {self.issue}"


    class Meta:
        constraints = [
            models.CheckConstraint(
                models.Q(status__in=ticketStatus.values)
                ),
        ]

At the moment, I'm getting this error when I attempt the migration:

TypeError: __init__() takes 1 positional argument but 2 were given

I believe this is associated with models.Q(status__in=ticketStatus.values)

I'm currently using Django version 3.2.4

Upvotes: 2

Views: 793

Answers (1)

user12065892
user12065892

Reputation:

CheckConstraint accept two-argument

name and check both are mandatory argument

Try below this, it works well

CheckConstraint(check=Q(status__in=ticketStatus.values), name='ticketStatus') 

More details can be found here: https://docs.djangoproject.com/en/3.2/ref/models/constraints/#checkconstraint

Upvotes: 2

Related Questions