문제

고 말할 수 있습니다 나는 다음과 같은 장고의 모델로:

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 것이 아마 우수한 캐싱로 근처에 위치하고 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top