2

次の 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')

これははるかに優れています。特定の言語ですべてのラベルを要求し、それらを 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)

オプション 2 を実装しましたが、非常に見にくいと思います。group_id フィールドが気に入らず、これ以上の名前が思い浮かびません。さらに、私が使用している StandardLabel は抽象モデルであり、これをサブクラス化して、さまざまなフィールドのさまざまなラベル セットを取得します。

オプション 3 がデータベースにヒットしなかった場合は、それを選択すると思います。本当の問題は、フィルターがインスタンスをtext__language=1キャッシュしないことだと思います。LabelTexttext.get(language=1)

これについてどう思いますか?誰でもよりクリーンなソリューションを推奨できますか?

編集:明確にするために、これらはフォームラベルではないため、Django 国際化システムは役に立ちません。

4

4 に答える 4

3

もちろん、アプリケーションの設計にもよりますが、考慮すべきもう 1 つのオプションは、Django の国際化機能を利用することです。彼らが使用するアプローチは、デスクトップ ソフトウェアで見られるアプローチと非常によく似ています。

Djangoの国際化への参照を追加するために質問が編集されたので、それについては知っていますが、Djangoのintl機能はフォームだけではありません。それは非常に多くのことに影響し、アプリのデザインを少し調整するだけで済みます。

彼らのドキュメントはここにあります: http://docs.djangoproject.com/en/dev/topics/i18n/#topics-i18n

モデルを言語が 1 つしかないかのように定義するという考え方です。言い換えれば、言語にはまったく言及せず、たとえば英語だけをモデルに入れます。

そう:

class StandardLabel(models.Model):
    abbreviation = models.CharField(max_length=255)
    label = models.CharField(max_length=255)

言語の問題を完全に破棄したように見えますが、実際には場所を移動しただけです。言語がデータ モデルにある代わりに、それをビューにプッシュしました。

django の国際化機能を使用すると、テキスト翻訳ファイルを生成でき、テキストをシステムからファイルに取り出すための多くの機能が提供されます。これは、翻訳者に平文のファイルを送信できるため、翻訳者の仕事が容易になるため、実際には非常に便利です。新しい言語の追加は、ファイルを新しい言語に翻訳するのと同じくらい簡単です。

翻訳ファイルは、データベースからのラベルとその言語の翻訳を定義します。モデル、管理ビュー、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このアプローチはうまくいかないかもしれません。それでも、国際化プロジェクトを見てください。「そのまま」使用できるか、ドメインで機能する django に適したソリューションに触発される可能性があります。

于 2009-03-05T19:51:20.523 に答える
2

私は物事をできるだけシンプルに保ちます。次のようなものを使用すると、ルックアップが高速になり、コードがきれいになります。

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')
于 2009-03-05T19:38:25.873 に答える
1

言語ごとに新しいモデル インスタンスを追加するよりも、言語ごとにフィールドを追加する方がはるかに望ましいと思います。新しい言語を追加するときはスキーマの変更が必要ですが、それは難しくありません。どのくらいの頻度で言語を追加すると予想されますか? 当面は、データベースのパフォーマンスが向上し (結合やインデックスが追加されることはありません)、翻訳によってクエリ ロジックを台無しにする必要はありません。それが属しているテンプレートにすべて保管してください。

さらに良いことに、django-transmetadjango-modeltranslationなどの再利用可能なアプリを使用すると、このばかげた単純さとほぼ完全な透明性が得られます。

于 2009-03-06T19:26:19.903 に答える