twohot
twohot

Reputation: 58

How to replicate SQL Check Constraint (with Length Function) in Django Models

I created a table with SQL in Postgresql. Now, I am trying to replicate the same via Django models.

The SQL:

CREATE TABLE IF NOT EXISTS EntryMode
(
    ModeID SMALLSERIAL PRIMARY KEY
  , Name TEXT NOT NULL
        UNIQUE
  , Acronym TEXT NOT NULL
        UNIQUE
  ,
    CONSTRAINT name_char_length CHECK (length(Name) < 51)
  ,
    CONSTRAINT Acronym_char_length CHECK (length(Acronym) < 9)
);

The attempt using Django Model:

from django.db import models
from django.db.models.functions import Length

models.CharField.register_lookup(Length)
 
class EntryMode(models.Model):
    modeid = models.SmallAutoField(primary_key=True)
    name = models.TextField(unique=True)
    acronym = models.TextField(unique=True)

    class Meta:
        managed = True
        db_table = "entrymode"
        constraints = [
            models.CheckConstraint(
                name="name_char_length",
                check=models.Q(name__length__lt=51),
            ),
            models.CheckConstraint(
                name="acronym_char_length",
                check=models.Q(acronym__length__lt=9),
            ),
        ]

The outcome: I get an error message and a traceback:

django.core.exceptions.FieldError: Unsupported lookup 'length' for TextField or join on the field not permitted.

What am I doing wrong?

Upvotes: 1

Views: 186

Answers (1)

twohot
twohot

Reputation: 58

Silly me. I spotted the issue

The error was on Line 4:

models.CharField.register_lookup(Length)

Line 4 registers the Length function for CharField; but the Constraints in EntryMode model are checking TextField attributes instead. Length function was not registered for TextField therefore the constraint could not check character lengths that field (migration fails). Correcting line 4 fixed the issue.

Fix:

models.TextField.register_lookup(Length)

Upvotes: 2

Related Questions