Skip to main content

Django i18n: Uluslararasılaştırma ve çeviri rehberi

settings.py'den üretime: Django'nun çeviri sistemini yapılandırın, PO dosyaları yazın, çoğulları yönetin ve çevirileri yapay zeka ile otomatikleştirin.

1

Kurun ve dizeleri ayıklayın

Django'nun i18n çerçevesi yerleşiktir -- yalnızca etkinleştirmeniz gerekir. Akıllı yerel ayar geri dönüşleri için django-locale-chain'i yükleyin, ardından çevrilebilir dizeleri Python kodunuzdan ve şablonlarınızdan PO dosyalarına ayıklamak için makemessages kullanın.

Django arka planda GNU gettext kullanır. makemessages komutu kodunuzu gettext çağrıları ve şablon etiketleri için tarar, ardından .po dosyaları oluşturur. Çeviriden sonra compilemessages, çalışma zamanında hızlı arama yapılması için bunları ikili .mo dosyalarına dönüştürür.
Terminal
pip install django-locale-chain
Terminal
# Extract all translatable strings from Python and template files
python manage.py makemessages -l de -l ja -l es -l fr

# After translating .po files, compile to .mo (binary)
python manage.py compilemessages

# Project structure after running makemessages:
# locale/
# ├── de/
# │   └── LC_MESSAGES/
# │       ├── django.po    <-- translate this
# │       └── django.mo    <-- compiled (auto-generated)
# ├── ja/
# │   └── LC_MESSAGES/
# │       ├── django.po
# │       └── django.mo
# └── es/
#     └── LC_MESSAGES/
#         ├── django.po
#         └── django.mo
2

Ayarları ve ara yazılımı yapılandırın

settings.py içinde USE_I18N = True ayarını yaparak, desteklediğiniz LANGUAGES listesini tanımlayarak ve MIDDLEWARE yığınınıza LocaleMiddleware ekleyerek uluslararasılaştırmayı etkinleştirin. LocaleMiddleware kullanıcının dilini URL ön ekinden, oturumdan, çerezlerden veya Accept-Language üstbilgisinden algılar.

settings.py
# settings.py

from django.utils.translation import gettext_lazy as _

# Default language
LANGUAGE_CODE = 'en'

# Enable i18n
USE_I18N = True
USE_L10N = True

# Languages your site supports
LANGUAGES = [
    ('en', _('English')),
    ('de', _('German')),
    ('ja', _('Japanese')),
    ('es', _('Spanish')),
    ('fr', _('French')),
    ('pt-br', _('Brazilian Portuguese')),
]

# Where Django looks for .po files
LOCALE_PATHS = [
    BASE_DIR / 'locale',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',       # <-- enables i18n
    'locale_chain.middleware.LocaleChainMiddleware',    # <-- smart fallbacks
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
LocaleMiddleware, SessionMiddleware'den sonra (oturumu okur) ve CommonMiddleware'den önce gelmelidir. Yanlış sıraya yerleştirilirse dil algılama herhangi bir hata göstermeden başarısız olur ve tüm kullanıcılar varsayılan LANGUAGE_CODE değerini görür.

URL uluslararasılaştırması

URL'lerinize etkin dil kodunu otomatik olarak eklemek için i18n_patterns() kullanın. Bu, her dile kendi URL ad alanını (/en/about/, /de/about/) verir; SEO açısından daha iyidir ve kullanıcıların dile özgü bağlantıları paylaşabilmesini sağlar.

urls.py
# urls.py
from django.conf.urls.i18n import i18n_patterns
from django.urls import path, include

urlpatterns = [
    # Non-localized URLs (API, admin, etc.)
    path('api/', include('api.urls')),
]

urlpatterns += i18n_patterns(
    # These get prefixed with the language code: /en/about/, /de/about/
    path('', include('myapp.urls')),
    path('admin/', admin.site.urls),
    prefix_default_language=False,  # Skip prefix for default language
)
3

Dizeleri çeviri için işaretleyin

Django iki temel çeviri işlevi sağlar: istek sırasında değerlendirilen dizeler için gettext() (_() olarak da adlandırılır) ve içe aktarma sırasında değerlendirilen dizeler için gettext_lazy(). Şablonlarda {% trans %} ve {% blocktrans %} etiketlerini kullanın.

Görünümlerde (Python kodu)

views.py
from django.utils.translation import gettext as _
from django.utils.translation import ngettext
from django.http import HttpResponse

def greeting_view(request):
    # Simple translation
    welcome = _("Welcome to our site")

    # Translation with variables (Python string formatting)
    user_greeting = _("Hello, %(name)s!") % {"name": request.user.username}

    # Plurals
    count = request.user.order_set.count()
    order_text = ngettext(
        "You have %(count)d order.",
        "You have %(count)d orders.",
        count,
    ) % {"count": count}

    return HttpResponse(f"{welcome}<br>{user_greeting}<br>{order_text}")

Şablonlarda

templates/myapp/index.html
{# Load the i18n template tags #}
{% load i18n %}

{# Simple translation #}
<h1>{% trans "Welcome to our site" %}</h1>

{# Translation with variables #}
{% blocktrans with name=user.username %}
  Hello, {{ name }}!
{% endblocktrans %}

{# Plurals in templates #}
{% blocktrans count count=order_count %}
  You have {{ count }} order.
{% plural %}
  You have {{ count }} orders.
{% endblocktrans %}

{# Mark strings as translatable but don't output them (for attributes, etc.) #}
{% trans "Submit" as submit_label %}
<button type="submit">{{ submit_label }}</button>

Modellerde ve formlarda

models.py
from django.db import models
from django.utils.translation import gettext_lazy as _

class Product(models.Model):
    name = models.CharField(_("product name"), max_length=200)
    description = models.TextField(_("description"), blank=True)

    class Meta:
        verbose_name = _("product")
        verbose_name_plural = _("products")

    def __str__(self):
        return self.name

# IMPORTANT: Use gettext_lazy (_) for anything evaluated at import time:
# - Model field labels, verbose_name, help_text
# - Form field labels
# - Class-level attributes
# Use gettext for anything evaluated at request time:
# - View functions, template tags
Model alanlarında, form etiketlerinde veya sınıf düzeyindeki özniteliklerde gettext_lazy() yerine gettext() kullanılması, dizelerin her istekte değil içe aktarma sırasında (sunucu başlatıldığında) bir kez çevrilmesine neden olur. Çeviri, içe aktarma sırasında etkin olan dilde -- genellikle varsayılan LANGUAGE_CODE değerinde -- sabit kalır.

PO dosya biçimi

makemessages çalıştırıldıktan sonra Django her dil için .po (Portable Object) dosyaları oluşturur. Bunlar msgid/msgstr çiftlerini içerir. msgstr değerlerini çevirin, ardından Django'nun çalışma zamanında okuduğu ikili .mo dosyalarını oluşturmak için compilemessages çalıştırın.

locale/de/LC_MESSAGES/django.po
# locale/de/LC_MESSAGES/django.po

msgid "Welcome to our site"
msgstr "Willkommen auf unserer Seite"

msgid "Hello, %(name)s!"
msgstr "Hallo, %(name)s!"

#, python-format
msgid "You have %(count)d order."
msgid_plural "You have %(count)d orders."
msgstr[0] "Sie haben %(count)d Bestellung."
msgstr[1] "Sie haben %(count)d Bestellungen."

msgid "product name"
msgstr "Produktname"

msgid "description"
msgstr "Beschreibung"

msgid "product"
msgstr "Produkt"

msgid "products"
msgstr "Produkte"

msgid "Submit"
msgstr "Absenden"
4

Çoğulları ve değişkenleri yönetin

Django çoğullaştırma için GNU gettext'in çoğul kurallarını izleyen ngettext() işlevini kullanır. Her dil, kaç çoğul biçime sahip olduğunu ve doğru biçimi seçme formülünü tanımlar. PO dosyaları bunu bir Plural-Forms üstbilgisiyle bildirir.

Plural forms by language
# English: 2 forms (singular, plural)
msgid "%(count)d item"
msgid_plural "%(count)d items"
msgstr[0] "%(count)d item"
msgstr[1] "%(count)d items"

# German: 2 forms (singular, plural)
msgstr[0] "%(count)d Artikel"
msgstr[1] "%(count)d Artikel"

# Russian: 3 forms (one, few, many)
msgstr[0] "%(count)d товар"        # 1 item
msgstr[1] "%(count)d товара"       # 2-4 items
msgstr[2] "%(count)d товаров"      # 5+ items

# Arabic: 6 forms (zero, one, two, few, many, other)
msgstr[0] "لا عناصر"               # 0
msgstr[1] "عنصر واحد"              # 1
msgstr[2] "عنصران"                 # 2
msgstr[3] "%(count)d عناصر"        # 3-10
msgstr[4] "%(count)d عنصرًا"       # 11-99
msgstr[5] "%(count)d عنصر"         # 100+

# Japanese: 1 form (no plural distinction)
msgstr[0] "%(count)d個のアイテム"

# In Python code, always use ngettext:
from django.utils.translation import ngettext

msg = ngettext(
    "%(count)d item",
    "%(count)d items",
    count,
) % {"count": count}
gettext çağrılarında hiçbir zaman Python f-string'lerini veya .format() işlevini kullanmayın. Çeviri ayıklayıcısı bunları ayrıştıramaz. Eski biçem %() biçimlendirmesini kullanın: _('Merhaba, %(name)s!') % {'name': name}. Bu, çevirmenlerin değişken yer tutucularını PO düzenleyicilerinde görmesini de sağlar.

Çeviri kalitesini otomatikleştirin

Eksik anahtarları ve bozuk yer tutucuları yayımlanmadan önce i18n-validate ile yakalayın. Gerçek çeviriler gelmeden önce kullanıcı arayüzünüzü i18n-pseudo ile sözde çeviriler kullanarak sınayın.

Yaygın hatalar

gettext() ve gettext_lazy() karışıklığı

Model alanları, form etiketleri ve içe aktarma sırasında değerlendirilen sınıf düzeyindeki tüm öznitelikler için gettext_lazy() (_ olarak içe aktarılır) kullanın. Görünüm işlevleri ve istek sırasında çalışan kod için gettext() kullanın. Bunları karıştırmak çevirileri sunucunun başlangıç dilinde sabitler.

compilemessages çalıştırmayı unutmak

Django .po dosyalarını değil derlenmiş .mo dosyalarını okur. Bir .po dosyasını düzenleyip 'python manage.py compilemessages' komutunu çalıştırmazsanız değişiklikleriniz görünmez. compilemessages komutunu dağıtım betiğinize ekleyin.

LOCALE_PATHS'in yapılandırılmaması

LOCALE_PATHS boşsa veya yanlış klasörü gösteriyorsa makemessages .po dosyalarını yanlış yerde oluşturur ve Django çalışma zamanında bunları bulamaz. Her zaman LOCALE_PATHS = [BASE_DIR / 'locale'] ayarını yapın ve klasörün var olduğunu doğrulayın.

URL'lerde i18n_patterns'in eksik olması

i18n_patterns() olmadan URL'lerde dil ön eki bulunmaz ve Django dil algılama için yalnızca çerezlere/üstbilgilere güvenir. Bu durum SEO'ya zarar verir (dile özgü URL'ler olmaz) ve URL üzerinden dil değiştirmeyi bozar. Kullanıcılara yönelik URL kalıplarınızı i18n_patterns() ile sarın.

django-locale-chain ile akıllı yerel ayar geri dönüşleri

Django'nun çeviri sistemi, bölgesel bir çeşit eksik olduğunda doğrudan LANGUAGE_CODE değerine döner. pt-BR kullanan biri, pt-PT çevirileriniz olsa bile İngilizce metni görür. django-locale-chain, gettext geri dönüş zincirleri kurarak bunu düzeltir: pt-BR önce pt-PT'yi, ardından pt'yi dener ve son olarak varsayılan dilinize döner.

settings.py
# settings.py -- Smart fallback with django-locale-chain
# pip install django-locale-chain

MIDDLEWARE = [
    # ...
    'django.middleware.locale.LocaleMiddleware',
    'locale_chain.middleware.LocaleChainMiddleware',  # after LocaleMiddleware
    # ...
]

# That's it! 75 built-in fallback chains are now active:
# pt-BR user → tries pt-PT → tries pt → falls back to LANGUAGE_CODE
# es-MX user → tries es-419 → tries es → falls back to LANGUAGE_CODE
# fr-CA user → tries fr → falls back to LANGUAGE_CODE

# Optional: customize specific chains
LOCALE_FALLBACK_CHAINS = {
    "pt-BR": ["pt-PT", "pt"],
    "es-MX": ["es-419", "es"],
    "fr-CA": ["fr"],
}

# Or configure programmatically in AppConfig.ready():
from locale_chain import configure

class MyAppConfig(AppConfig):
    name = "myapp"

    def ready(self):
        configure(overrides={"zh-Hant-HK": ["zh-Hant-TW", "zh-Hant"]})

Önerilen proje yapısı

Project Structure
myproject/
├── myproject/
│   ├── settings.py          # i18n config, MIDDLEWARE, LANGUAGES
│   ├── urls.py              # i18n_patterns for URL prefixing
│   └── wsgi.py
├── myapp/
│   ├── models.py            # gettext_lazy for field labels
│   ├── views.py             # gettext for request-time strings
│   └── templates/
│       └── myapp/
│           └── index.html   # {% load i18n %}, {% trans %}, {% blocktrans %}
├── locale/                  # Created by makemessages
│   ├── de/
│   │   └── LC_MESSAGES/
│   │       ├── django.po    # German translations
│   │       └── django.mo    # Compiled binary
│   ├── ja/
│   │   └── LC_MESSAGES/
│   │       ├── django.po
│   │       └── django.mo
│   └── es/
│       └── LC_MESSAGES/
│           ├── django.po
│           └── django.mo
├── manage.py
└── requirements.txt

i18n Agent'ı şimdi deneyin

Çeviri dosyanızı buraya bırakın

JSON, YAML, PO, XML, CSV, Markdown, Properties

veya göz atmak için tıklayın

Hedef diller

Kayıt gerekmezAnında fiyat tahmini

django-locale-chain ile yerel ayar geri dönüşü

pt-BR gibi bölgesel bir yerel ayarda çeviri anahtarı eksik olduğunda Django, önce üst yerel ayar pt'yi denetlemek yerine doğrudan şablon diline geçer.

Terminal
pip install django-locale-chain
Configuration
# settings.py
LOCALE_CHAINS = {
    'pt-BR': ['pt', 'es', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
}

MIDDLEWARE = [
    ...
    'django_locale_chain.middleware.LocaleChainMiddleware',
    ...
]

Desteklenen çerçevelerin tam listesi ve 75 yerleşik zincir için Yerel Ayar Geri Dönüşü Rehberimize bakın. Learn more →

Sık sorulan sorular