[Django]-How to make my models follow DRY principles

2đź‘Ť

âś…

Using abstract base models:

class JobAd(models.Model):
    title = models.CharField(max_length=225)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

    class Meta:
        abstract = True

class PostFirstJobAd(JobAd):
    pass

class PostSecondJobAd(JobAd):
    pass

class PostThirdJobAd(JobAd):
    pass

This would create 3 tables. The base class JobAd does not have a table in the db.

Since you appear to have 3 different models with the exact same code, you should question whether you really need 3 different models at all. Another option is to just store them all in one table, and add another field for the “other” thing.

class JobAd(models.Model):
    pos = models.CharField(max_length=100, choices=['first', 'second', 'third'])
    title = models.CharField(max_length=225)
    description = models.TextField()
    created_at = models.DateTimeField(auto_now=True)

An integer field for pos is also possible.

👤wim

1đź‘Ť

First off, the abstract models might be what you need here. Depending on the business requirements, you may need to think a little harder on the architecture.

If, in fact, you do need to use abstract base classes:

class BaseJob(models.Model):
    title = models.CharField(max_length=255)
    # etc...

    class Meta:
        abstract = True

    def method_1(self):
        # base methods that work for instance data

Once that is defined, you can implement the base class in a concrete model. A concrete model is a model that doesn’t use the abstract = True metaclass property (or proxy, etc.) like so:

class Job(BaseJob):
    pass

If you need additional fields you can define them like any other model field but when you run makemigrations you’ll find the fields get added in the migration generated.

Leave a comment