Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using models instead of choices for enumerations in Django

Tags:

python

django

I am currently building a simple application in Django and am trying to settle on a good model design.

First Approach

In the Django documentation and many blog posts I have read, the choice keyword argument is recommended. This would be implemented in my (simplified) noun model like so:

class Noun(models.Model):
    FEMININE = 0
    MASCULINE = 1
    NEUTER = 2
    COMMON = 3
    GENDER_TYPE = (
        (FEMININE, "Feminine"),
        (MASCULINE, "Masculine"),
        (NEUTER, "Neuter"),
        (COMMON, "Common"),
    )
    stem = models.CharField(max_length=200)
    gender = models.IntegerField(choices=GENDER_TYPE, default=Noun.COMMON)

Second Approach

When I walked across the hallway and spoke to a db admin friend about how he would indicate enumerations in a database, he acknowledged debate but said that he would make a table for each enumeration and reference it by foreign key. This approach maps almost exactly to the following models:

class Gender(models.Model):
    short_name = models.CharField(max_length=1) # M, F, N, or C
    description = models.CharField(max_length=20) # Masculine, Feminine, Neuter, or Common

class Noun(models.Model):
    stem = models.CharField(max_length=200)
    gender = models.ForeignKey(Gender, on_delete=models.CASCADE)

I am trying to weigh the relative merits of each approach. Here are the pro's and con's I can discern:

First Approach

  1. Encapsulated
  2. No need to import a "Gender" model
  3. Does not require extra step of populating enumeration values in the database
  4. Easier to read in the code: I do not need to look at the database to see the valid values

Second Approach

  1. Much more flexible: I can change all feminine words to masculine in one step, or add a new gender without having to modify the noun table
  2. The logic is enforced by a foreign key constraint rather than the code, preserving data integrity

So, my question: Am I missing something obvious about why one approach is invalid? If both approaches are valid, which approach is better?

like image 969
brianpck Avatar asked Dec 24 '22 08:12

brianpck


1 Answers

Both approaches are valid. To decide on one, you should consider mostly two points: how many choices you got, and how likely they will change in the future.

So, if there're few choices and they are unlikely to change often, use choices instead of foreign key - it will be better from performance point of view. If there're many choices or they change often - go for foreign key.

In case with genders, I would choose choices. Even if they change in future - existing ones most likely won't be affected.

like image 188
Nikita Avatar answered Feb 16 '23 09:02

Nikita