curt
curt

Reputation: 4592

How to Constrain a Django Model Table to One Row

I want to create a table with only one row in MySQL database. It's for site settings. This is the SQL for it that I found in another question on this site:

CREATE TABLE T1(
Lock char(1) not null DEFAULT 'X',
/* Other columns */,
constraint PK_T1 PRIMARY KEY (Lock),
constraint CK_T1_Locked CHECK (Lock='X')
)

Can I do this in a Django model program? So far, I have:

from django.db import models

class Settings(models.Model):
    lock = models.CharField(max_length=1, null=False, primary_key=True, default='X')
    employer_day_date = models.DateField

    class Meta:
        constraints = [CheckContraint()]

I can add class Meta: to it, but PyCharm doesn't recognize CheckConstraint so I haven't gone any further with it. I have no problems doing it in SQL if that's the only way.

I was thinking of altering the database after the migration, but it seemed rather crude.

Solution

I used @ruddra code and some from the article he sited:

class SiteSettings(models.Model):
lock = models.CharField(max_length=1, null=False, primary_key=True, default='X')
employer_day_date = models.DateField()

def save(self, *args, **kwargs):
   self.pk = 'X'
   super().save(*args, **kwargs)

def delete(self, *args, **kwargs):
   pass

@classmethod
def load(cls):
    obj, created = cls.objects.get_or_create(pk='X')
    return obj

After running migrate, I registered the Class in admin and then viewed the table in admin. There were no rows. I don't know if the load class method didn't work or load wasn't called. Once the row is set up, it's no longer needed. I tested the delete. I asked me if I was sure I wanted to delete it. I chose yes. The row was still there afterwards.

Upvotes: 2

Views: 1707

Answers (1)

ruddra
ruddra

Reputation: 51988

Basically you are trying to achieve Singleton pattern in Django models. So, here you can override the save method here:

from django.db import models

class Settings(models.Model):
    lock = models.CharField(max_length=1, null=False, primary_key=True, default='X')
    employer_day_date = models.DateField()

    def save(self, *args, **kwargs):
       self.pk = 'X'
       super().save(*args, **kwargs)

The answer is based on this article, there you can find some nice examples on how to use Singleton pattern in Django models.

Upvotes: 3

Related Questions