ブログに戻る

AIを使ったDjangoデータベースコンテンツの翻訳方法

2026-02-18 3 分で読める
AIを使ったDjangoデータベースコンテンツの翻訳方法

Djangoの組み込み国際化(i18n)フレームワークを使ったことがあれば、静的文字列をうまく処理できることをご存知でしょう。テキストをgettext()でラップしたり、{% trans %}テンプレートタグを使用すると、文字列が.poファイルに抽出され、翻訳者がそれを埋めます。このシステムは実戦で検証済みで、コードやテンプレートに対して非常にうまく機能します。

しかし、データベースに保存されたコンテンツはどうでしょうか?

商品名、記事タイトル、カテゴリの説明、FAQの回答、ユーザー生成コンテンツ。これらはどれもソースコードに存在しません。Djangoのmakemessagesコマンドではこれらを見つけることはできず、.poファイルも役に立ちません。アプリケーションが複数の言語でユーザーに動的コンテンツを提供する場合、別の戦略が必要です。

その方法はこうです:django-modeltranslationを使ってモデルに翻訳可能なフィールドを追加し、TranslateBot を使ってAIで翻訳を自動化します。

Djangoデータベース翻訳パッケージ

いくつかのサードパーティパッケージがデータベース翻訳の問題を解決しており、それぞれ異なるアーキテクチャを持っています。

django-modeltranslation

既存のテーブルに直接言語固有のカラムを追加します。titleフィールドはtitle_entitle_detitle_frなどになります。すべてが同じテーブルにあるため、クエリは高速のままです。管理画面ではすべての言語が並んで表示されます。

django-parler

各モデルに対して別の翻訳テーブルを作成します。元のテーブルはクリーンなまま保たれ、翻訳は外部キーで結合された関連テーブルに保存されます。

django-translations

任意のモデルを指すジェネリック外部キーを持つ単一の翻訳テーブルを使用します。すべてのモデルのすべての翻訳が1つのテーブルに格納されます。

手動JSONフィールド

JSONFieldに翻訳を保存できます:

class Product(models.Model):
    name_translations = models.JSONField(default=dict)
    # {"en": "Running Shoes", "de": "Laufschuhe", "fr": "Chaussures de course"}

どれを使うべきか?

ほとんどのプロジェクトでは、django-modeltranslationが最良の選択です。最も成熟したパッケージで、Django管理画面との統合が最も優れており、高速クエリのためにすべてのデータを同じテーブルに保持します。トレードオフ(広いテーブルと新しい言語ごとのマイグレーション)は、大多数のアプリケーションにとって管理可能です。このガイドの残りはdjango-modeltranslationを使用します。

django-modeltranslationのステップバイステップ設定

ステップ1:パッケージのインストール

TranslateBotはdjango-modeltranslationをオプション依存関係としてバンドルしています。両方を一度にインストールします:

pip install translatebot-django[modeltranslation]

またはuvを使用している場合:

uv add --dev translatebot-django[modeltranslation]

ステップ2:Django設定の構成

settings.pyで重要なのは2つ:アプリの順序と言語リストです。

# settings.py

INSTALLED_APPS = [
    'modeltranslation',          # Must be BEFORE django.contrib.admin
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Your apps
    'shop',
    'translatebot_django',
]

LANGUAGE_CODE = 'en'

LANGUAGES = [
    ('en', 'English'),
    ('de', 'German'),
    ('fr', 'French'),
    ('nl', 'Dutch'),
]

modeltranslationアプリはdjango.contrib.adminの前に配置する必要があります。これにより、管理クラスにパッチを当てて翻訳フィールドを表示できるようになります。

ステップ3:翻訳用モデルの登録

翻訳可能なモデルがある各アプリにtranslation.pyファイルを作成します。ECサイトのショップアプリの場合:

# shop/translation.py

from modeltranslation.translator import register, TranslationOptions
from .models import Product, Category


@register(Product)
class ProductTranslationOptions(TranslationOptions):
    fields = ('name', 'description', 'short_description')


@register(Category)
class CategoryTranslationOptions(TranslationOptions):
    fields = ('name', 'description')

人間が読めるテキストを含むフィールドのみ含めてください。slugpriceskuなどのフィールドは登録しないでください。

ステップ4:マイグレーションの作成と実行

python manage.py makemigrations
python manage.py migrate

この後、shop_productテーブルに新しいカラムが追加されます:

カラム
name varchar(200)
name_en varchar(200)
name_de varchar(200)
name_fr varchar(200)
name_nl varchar(200)
description text
description_en text
description_de text
description_fr text
description_nl text
short_description text
short_description_en text
short_description_de text
short_description_fr text
short_description_nl text

LANGUAGESで定義した各言語が、登録されたフィールドごとに独自のカラムを持ちます。

問題:空の翻訳フィールド

スキーマは整いましたが、すべての_de_fr_nlカラムが空です。3つの翻訳可能なフィールドと3つの対象言語を持つ500個の商品がある場合、埋める必要のある4,500個の空のフィールドがあります。

このコンテンツを手動で翻訳するのは現実的ではありません。プロの翻訳サービスを使っても、データをエクスポートし、送信し、納品を待ち、結果をインポートし直す必要があります。小さなチームやソロ開発者にとって、これは通常その機能が永遠にリリースされないことを意味します。

ここでTranslateBotの出番です。

TranslateBotで翻訳を自動化する

TranslateBotのtranslate管理コマンドは、AIを使ってこれらの空のフィールドをすべて埋めることができます。まずAPIキーを設定します:

# settings.py

TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"  # Fast and cost-effective

次に、登録されたすべてのモデルを対象言語に翻訳します:

python manage.py translate --target-lang de --models

この1つのコマンドで、django-modeltranslationに登録されたすべてのモデルを見つけ、対象言語で空のフィールドを特定し、AI生成の翻訳で埋めます。

特定のモデルを翻訳する

商品だけを翻訳し、カテゴリは翻訳しない場合:

python manage.py translate --target-lang de --models Product

または複数の特定モデル:

python manage.py translate --target-lang de --models Product Category

ドライランでプレビュー

データベースに書き込む前に必ずプレビューしてください:

python manage.py translate --target-lang de --models --dry-run

これにより、レコードを変更せずに何が翻訳されるかを正確に確認できます。

既存コンテンツの再翻訳

デフォルトでは、TranslateBotはすでに翻訳があるフィールドをスキップします。既存の翻訳を上書きする場合(例:AIモデルの改善やコンテキストの追加後):

python manage.py translate --target-lang de --models --overwrite

すべての言語を一度に翻訳

--target-langを省略し、設定にLANGUAGESが定義されている場合、TranslateBotは設定されたすべての言語に翻訳します:

python manage.py translate --models

翻訳パイプラインの仕組み

翻訳コマンドを実行すると、以下のことが起こります。

  1. 検出。 TranslateBotはdjango-modeltranslationのレジストリをクエリして、登録されたすべてのモデルとその翻訳可能なフィールドを見つけます。

  2. ソース検出。 各レコードについて、ソースコンテンツを読み取ります。まずベースフィールド(例:name)をチェックし、次に最初に値が入っている言語固有フィールド(例:name_en)にフォールバックします。ソースコンテンツのないレコードはスキップされます。

  3. バッチ処理。 レコードはバッチにグループ化され、AIプロバイダーに送信されます。これによりAPI呼び出しが効率的になり、レート制限への到達を回避します。

  4. 翻訳。 各バッチは設定されたAIモデルを使用して翻訳されます。LiteLLMがサポートする任意のLLMプロバイダー(OpenAI、Anthropic、Google、Azureなど多数)やDeepLを使用できます。

  5. アトミック書き込み。 1回の翻訳実行のすべてのデータベース更新は、単一のトランザクションにラップされます。APIエラーやデータベース制約違反など、何か問題が発生した場合、部分的なデータは保存されません。全部か無しかです。

完全なワークフロー例

モデル定義から翻訳済みコンテンツまでの完全な例を、ECサイトのProductモデルを使って示します。

モデルの定義

# shop/models.py

from django.db import models


class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField()
    short_description = models.CharField(max_length=500, blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    sku = models.CharField(max_length=50, unique=True)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name

翻訳用に登録

# shop/translation.py

from modeltranslation.translator import register, TranslationOptions
from .models import Product


@register(Product)
class ProductTranslationOptions(TranslationOptions):
    fields = ('name', 'description', 'short_description')

マイグレーションの実行

python manage.py makemigrations shop
python manage.py migrate

翻訳コンテキストの追加(オプション)

プロジェクトルートにTRANSLATING.mdファイルを作成して、AIに商品ドメインのコンテキストを提供します:

# Translation Context

## About This Project
E-commerce store for outdoor sports equipment.

## Terminology
- "trail runners" refers to trail running shoes, not people
- Keep brand names (Nike, Salomon, Arc'teryx) untranslated
- "Gore-Tex" is a brand name, do not translate

## Tone
- Use informal "du" form in German
- Product descriptions should sound enthusiastic but not exaggerated

翻訳

# Preview first
python manage.py translate --target-lang de --models Product --dry-run

# Apply translations
python manage.py translate --target-lang de --models Product

出力:

Translating Product model fields to German (de)...
Found 142 products with untranslated fields
Translating batch 1/15...
Translating batch 2/15...
...
Translating batch 15/15...
Successfully translated 142 products

管理画面で確認

Django管理画面を開いて任意の商品にアクセスしてください。翻訳フィールドが入力されているのが確認できます:

各対象言語で繰り返します:

python manage.py translate --target-lang fr --models Product
python manage.py translate --target-lang nl --models Product

またはすべての言語を一度に翻訳:

python manage.py translate --models Product

ベストプラクティス

本番環境で一括翻訳を実行する前にデータベースをバックアップしてください。TranslateBotはアトミックトランザクションを使用するため、失敗した実行で部分的なデータが残ることはありません。ただし、バックアップがあれば、翻訳品質が期待通りでない場合に戻す方法があります。

# PostgreSQL example
pg_dump mydb > backup_before_translation.sql

まずドライランを使用してください。新しいモデルや言語に翻訳を適用する前に、必ず--dry-runで実行してください。ソースコンテンツが正しく検出され、翻訳が妥当に見えることを確認するために出力を確認してください。

大規模なデータベースでは一度に1つのモデルを翻訳してください。これにより結果の確認が容易になり、必要に応じて特定のモデルを再実行できます。

python manage.py translate --target-lang de --models Product
python manage.py translate --target-lang de --models Category
python manage.py translate --target-lang de --models Article

翻訳コンテキストを追加してください。ドメイン固有の用語とトーンガイドラインを含むTRANSLATING.mdファイルは、翻訳品質を大幅に向上させます。これは医療、法律、技術製品などの専門分野で特に重要です。

ソース言語を常に入力してください。TranslateBotはベースフィールドまたはソース言語フィールドから読み取ります。データ入力ワークフローが常にソース言語を入力するようにしてください。空のソースフィールドは空の翻訳を意味します。

完全なカバレッジのためにPOファイル翻訳と組み合わせてください。コード文字列とデータベースコンテンツの両方を翻訳します:

# Static strings in code and templates
python manage.py makemessages -l de -l fr -l nl
python manage.py translate
python manage.py compilemessages

# Dynamic content in the database
python manage.py translate --models

こうすることで、テンプレートからでもデータベースからでも、ユーザーが目にするすべての文字列が翻訳されます。

次のステップ

.po ファイルの手動編集をやめよう

TranslateBot は AI を使って Django の翻訳を自動化します。コマンド一つで、すべての言語を、わずかなコストで。