简体   繁体   中英

Using models instead of choices for enumerations in 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?

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.

Your understanding of both approaches pros and cons is correct. In a case of a small project you can use any approach without any problems at all. However, if you expect your project to be large enough, you should pay attention to the next 2 moments:

  1. If choices list might grow in time it will be easier to have it as a Gender model.
  2. If choices list is undoubtedly constant - use gender field with choices atribute. This will save you some time on making a query of unnecessary Gender model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM