Допустим, у меня есть следующая модель Django:
class StandardLabel(models.Model):
id = models.AutoField(primary_key=True)
label = models.CharField(max_length=255)
abbreviation = models.CharField(max_length=255)
Каждая метка имеет идентификационный номер, текст метки и сокращение. Теперь я хочу перевести эти ярлыки на другие языки. Каков наилучший способ сделать это?
На мой взгляд, у меня есть несколько вариантов:
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 не помогает.