Django 라벨 및 번역본 모델을 디자인
-
03-07-2019 - |
문제
고 말할 수 있습니다 나는 다음과 같은 장고의 모델로:
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')
이것은 훨씬 더 나은 지금,나를 요청할 수 있는 모든 레이블을 가진 특정 언어로 던져 dict:
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)
구현했 option2 지만,나는 그것에 매우 추-내가 좋아하지 않 group_id 분야,그리고 나는 아무것도 생각할 수 없다 더 나은 그것을 이름을 지정합니다.또한,StandardLabel 으로 나는 그것을 사용하는 추상적 모델,어느 나는 하위 클래스로 다양한 라벨 세트를 다양한 필드가 있습니다.
나는 가정 옵션의 경우 3/지 않았/중 데이터베이스에,그것은 내가 선택합니다.내가 믿는 진짜 문제는 필터 text__language=1
지 않는 캐시 LabelText
인스턴스,그래서 DB 이 칠 때 나 text.get(language=1)
에 대한 당신의 생각은 무엇입니까 이?할 수 있는 사람이 추천한 청정 솔루션?
편집:다만,그것은 명확하게하기 위해 이들은 형성하지 않는 레이블,이렇게 장고 국제화 시스템에 도움이 되지 않습니다.
해결책
언어 당 새 모델 인스턴스보다 언어 당 필드를 추가하는 것을 선호합니다. 새로운 언어를 추가 할 때 스키마 변경이 필요하지만 어렵지 않으며 얼마나 자주 언어를 추가 할 것으로 예상합니까? 그 동안 더 나은 데이터베이스 성능 (추가 된 조인 또는 색인 없음)을 제공하며 번역 작업으로 쿼리 로직을 멍청 할 필요가 없습니다. 모든 템플릿이 속한 템플릿에 보관하십시오.
더 좋은 점은 재사용 가능한 앱을 사용하십시오 장고 트랜스 맨타 또는 Django-ModelTranslation 그것은 이것을 간단하고 거의 완전히 투명하게 만듭니다.
다른 팁
물론 응용 프로그램 설계에 따라 고려할 수있는 또 다른 옵션은 Django의 국제화 기능을 사용하는 것입니다. 그들이 사용하는 접근법은 데스크탑 소프트웨어에서 발견 된 접근 방식에 매우 일반적입니다.
Django 국제화에 대한 참조를 추가하기 위해 질문이 편집되었으므로, 당신은 그것에 대해 알고 있지만, django의 INTL 기능은 단순한 형태 이상에 적용됩니다. 그것은 꽤 많이 터치하며 앱 디자인에 대한 몇 가지 조정 만하면됩니다.
그들의 문서는 여기에 있습니다. http://docs.djangoproject.com/en/dev/topics/i18n/#topics-i18n
아이디어는 모델을 하나의 언어 만있는 것처럼 정의한다는 것입니다. 다시 말해서, 언어를 전혀 언급하지 않고 모델에 영어 만 두십시오.
그래서:
class StandardLabel(models.Model):
abbreviation = models.CharField(max_length=255)
label = models.CharField(max_length=255)
나는 이것이 당신이 언어 문제를 완전히 버린 것처럼 보이지만 실제로 당신은 실제로 그것을 이전했습니다. 데이터 모델에있는 언어 대신보기로 푸시했습니다.
Django Internationalization 기능을 사용하면 텍스트 번역 파일을 생성 할 수 있으며 시스템에서 텍스트를 파일로 끌어 올릴 수있는 여러 기능을 제공합니다. 이것은 일반 파일을 번역기에 보낼 수 있으므로 작업을 더 쉽게 할 수 있기 때문에 실제로 유용합니다. 새 언어를 추가하는 것은 파일을 새로운 언어로 번역하는 것만 큼 쉽습니다.
번역 파일은 데이터베이스에서 레이블을 정의하고 해당 언어의 번역을 정의합니다. 모델, 관리자보기, JavaScript 및 템플릿에 대해 실행 시간에 동적으로 언어 번역을 처리하는 기능이 있습니다.
예를 들어 템플릿에서 다음과 같은 작업을 수행 할 수 있습니다.
<b>Hello {% trans "Here's the string in english" %}</b>
또는 뷰 코드에서는 다음을 수행 할 수 있습니다.
# See docs on setting language, or getting Django to auto-set language
s = StandardLabel.objects.get(id=1)
lang_specific_label = ugettext(s.label)
물론, 앱이 새로운 언어 입력에 관한 것이라면 on the fly
, 그러면이 접근법이 당신에게는 효과가 없을 수 있습니다. 그럼에도 불구하고 국제화 프로젝트를 살펴보십시오. "그대로"사용하거나 도메인에서 작동하는 장오에 적합한 솔루션에 영감을 얻을 수 있습니다.
나는 가능한 한 간단하게 유지할 것입니다. 조회가 더 빠르고 코드 클리너는 다음과 같은 것입니다.
class StandardLabel(models.Model):
abbreviation = models.CharField(max_length=255)
label = models.CharField(max_length=255)
language = models.CharField(max_length=2)
# or, alternately, specify language as a foreign key:
#language = models.ForeignKey(Language)
class Meta:
unique_together = ('language', 'abbreviation')
그런 다음 약어 및 언어를 기반으로 쿼리 :
l = StandardLabel.objects.get(language='en', abbreviation='suite')
지만 나와 함께 가 다니엘의 솔루션, 여기에 대체 무슨을에서 난에서 이해 귀하의 의견:
를 사용할 수 있습니다 XMLField 또 JSONField 을 저장하는 언어/번역 쌍이다.이 객체 참조하는 귀하의 상표를 사용하여 단일 id
에 대한 모든 번역.그리고 당신은 수 있는 사용자 지정 관리자 메소드를 호출하는 특정 번역:
Label.objects.get_by_language('ru', **kwargs)
또는 약간 깨끗하고 조금 더 복잡한 솔루션을과 잘 재생 admin
하는 것입 비정규화하여 XMLField 다른 모델을 많은 관계를 Label
모델입니다.동일한 API,하지만 그 대신 XML 구문 분석할 수 있 쿼리에 관련된 모델입니다.
모두에 대한 제안을 하나의 객체는 사용자의 레이블을 가리킵니다.
나지 않을 것에 대해 걱정하는 쿼리를 너무 많은,Django 캐시 쿼리와 당신의 DBMS 것이 아마 우수한 캐싱로 근처에 위치하고 있습니다.