在 Django 中使用模型而不是枚举选项

bri*_*pck 4 python django

我目前正在 Django 中构建一个简单的应用程序,并试图确定一个好的模型设计。

第一种方法

Django 文档和我读过的许多博客文章中choice推荐使用关键字参数。这将在我的(简化的)名词模型中实现,如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

第二种方法

当我穿过走廊并与一位数据库管理员朋友谈论他将如何在数据库中指示枚举时,他承认存在争议,但表示他将为每个枚举制作一个表并通过外键引用它。这种方法几乎完全映射到以下模型:

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)
Run Code Online (Sandbox Code Playgroud)

我试图权衡每种方法的相对优点。以下是我可以辨别的优点和缺点:

第一种方法

  1. 封装的
  2. 无需导入“性别”模型
  3. 不需要在数据库中填充枚举值的额外步骤
  4. 更容易阅读代码:我不需要查看数据库来查看有效值

第二种方法

  1. 更灵活:我可以一步将所有阴性词更改为阳性,或添加新性别而无需修改名词表
  2. 逻辑由外键约束而不是代码强制执行,从而保持数据完整性

所以,我的问题是:我是否遗漏了一些关于为什么一种方法无效的明显信息?如果两种方法都有效,哪种方法更好?

Nik*_*ita 6

这两种方法都是有效的。要做出决定,您应该主要考虑两点:您有多少选择,以及它们在未来发生变化的可能性有多大。

因此,如果选择很少并且它们不太可能经常更改,请使用选择而不是外键 - 从性能的角度来看会更好。如果有很多选择或者它们经常变化 - 选择外键。

如果有性别,我会选择选择。即使它们将来发生变化 - 现有的也很可能不会受到影响。


che*_*1st 6

您对这两种方法优缺点的理解是正确的。对于小型项目,您可以使用任何方法,没有任何问题。但是,如果您希望您的项目足够大,则应该注意以下注释:

  1. 如果选择列表可能会随着时间的推移而增长,那么将其作为模型就会更容易Gender
  2. 如果选择列表无疑是不变的 - 使用gender带有属性的字段choices。这将为您节省一些查询不必要Gender模型的时间。