假设我有以下 Django 模型:
class StandardLabel(models.Model):
id = models.AutoField(primary_key=True)
label = models.CharField(max_length=255)
abbreviation = models.CharField(max_length=255)
每个标签都有一个 ID 号、标签文本和缩写。现在,我想让这些标签可以翻译成其他语言。做这个的最好方式是什么?
在我看来,我有几个选择:
1:将翻译添加为模型上的字段:
class StandardLabel(models.Model):
id = models.AutoField(primary_key=True)
label_english = models.CharField(max_length=255)
abbreviation_english = models.CharField(max_length=255)
label_spanish = models.CharField(max_length=255)
abbreviation_spanish = models.CharField(max_length=255)
这显然不理想——添加语言需要编辑模型,正确的字段名称取决于语言。
2:添加语言作为外键:
class StandardLabel(models.Model):
id = models.AutoField(primary_key=True)
label = models.CharField(max_length=255)
abbreviation = models.CharField(max_length=255)
language = models.ForeignKey('languages.Language')
这好多了,现在我可以要求使用某种语言的所有标签,并将它们放入字典中:
labels = StandardLabel.objects.filter(language=1)
labels = dict((x.pk, x) for x in labels)
但这里的问题是标签 dict 是一个查找表,如下所示:
x = OtherObjectWithAReferenceToTheseLabels.object.get(pk=3)
thelabel = labels[x.labelIdNumber].label
如果每个标签有一行,这不起作用,一个标签可能有多种语言。为了解决这个问题,我需要另一个字段:
class StandardLabel(models.Model):
id = models.AutoField(primary_key=True)
group_id = models.IntegerField(db_index=True)
label = models.CharField(max_length=255)
abbreviation = models.CharField(max_length=255)
language = models.ForeignKey('languages.Language')
class Meta:
unique_together=(("group_id", "language"),)
#and I need to group them differently:
labels = StandardLabel.objects.filter(language=1)
labels = dict((x.group_id, x) for x in labels)
3:将标签文本扔到新模型中:
class StandardLabel(models.Model):
id = models.AutoField(primary_key=True)
text = models.ManyToManyField('LabelText')
class LabelText(models.Model):
id = models.AutoField(primary_key=True)
label = models.CharField(max_length=255)
abbreviation = models.CharField(max_length=255)
language = models.ForeignKey('languages.Language')
labels = StandardLabel.objects.filter(text__language=1)
labels = dict((x.pk, x) for x in labels)
但这不起作用,并且每次我引用标签的文本时都会导致数据库命中:
x = OtherObjectWithAReferenceToTheseLabels.object.get(pk=3)
thelabel = labels[x.labelIdNumber].text.get(language=1)
我已经实现了选项 2,但我觉得它非常难看 - 我不喜欢 group_id 字段,我想不出更好的名字来命名它。此外,我使用的 StandardLabel 是一个抽象模型,我将其子类化以获得不同字段的不同标签集。
我想如果选项 3 /没有/命中数据库,这就是我会选择的。我相信真正的问题是过滤器text__language=1
没有缓存LabelText
实例,所以当我点击数据库时text.get(language=1)
您对此有何看法?谁能推荐一个更清洁的解决方案?
编辑:为了清楚起见,这些不是表单标签,所以 Django 国际化系统没有帮助。