
Django i18n: Οδηγός διεθνοποίησης και μετάφρασης
Από το settings.py έως την παραγωγή: ρυθμίστε το σύστημα μετάφρασης του Django, δημιουργήστε αρχεία PO, διαχειριστείτε τους πληθυντικούς και αυτοματοποιήστε τις μεταφράσεις με AI.
Εγκαταστήστε και εξαγάγετε συμβολοσειρές
Το πλαίσιο i18n του Django είναι ενσωματωμένο — χρειάζεται απλώς να το ενεργοποιήσετε. Εγκαταστήστε το django-locale-chain για έξυπνες εναλλακτικές επιλογές γλώσσας και, στη συνέχεια, χρησιμοποιήστε το makemessages για να εξαγάγετε τις μεταφράσιμες συμβολοσειρές από τον κώδικα Python και τα πρότυπά σας σε αρχεία PO.
pip install django-locale-chain# 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Ρύθμιση παραμέτρων και middleware
Ενεργοποιήστε τη διεθνοποίηση στο settings.py ορίζοντας USE_I18N = True, καθορίζοντας τη λίστα των υποστηριζόμενων LANGUAGES και προσθέτοντας το LocaleMiddleware στη στοίβα MIDDLEWARE. Το LocaleMiddleware ανιχνεύει τη γλώσσα του χρήστη από το πρόθεμα του URL, τη συνεδρία, τα cookie ή την κεφαλίδα Accept-Language.
# 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',
]Διεθνοποίηση URL
Χρησιμοποιήστε το i18n_patterns() για να προσθέτετε αυτόματα στα URL σας το πρόθεμα του ενεργού κωδικού γλώσσας. Έτσι, κάθε γλώσσα αποκτά τον δικό της χώρο ονομάτων URL (/en/about/, /de/about/), κάτι που βελτιώνει το SEO και επιτρέπει στους χρήστες να κοινοποιούν συνδέσμους για συγκεκριμένη γλώσσα.
# 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
)Επισήμανση συμβολοσειρών για μετάφραση
Το Django παρέχει δύο κύριες συναρτήσεις μετάφρασης: τη gettext() (με ψευδώνυμο _()) για συμβολοσειρές που αξιολογούνται κατά την επεξεργασία ενός αιτήματος και τη gettext_lazy() για συμβολοσειρές που αξιολογούνται κατά την εισαγωγή. Στα πρότυπα, χρησιμοποιήστε τις ετικέτες {% trans %} και {% blocktrans %}.
Στα views (κώδικας Python)
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}")Στα πρότυπα
{# 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>Στα μοντέλα και τις φόρμες
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Μορφή αρχείων PO
Μετά την εκτέλεση του makemessages, το Django δημιουργεί αρχεία .po (Portable Object) για κάθε γλώσσα. Αυτά περιέχουν ζεύγη msgid/msgstr. Μεταφράστε τις τιμές msgstr και, στη συνέχεια, εκτελέστε το compilemessages για να δημιουργήσετε τα δυαδικά αρχεία .mo που διαβάζει το Django κατά την εκτέλεση.
# 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"Διαχείριση πληθυντικών και μεταβλητών
Το Django χρησιμοποιεί τη ngettext() για τον σχηματισμό πληθυντικού, ακολουθώντας τους κανόνες πληθυντικού του GNU gettext. Κάθε γλώσσα ορίζει πόσους τύπους πληθυντικού διαθέτει και τον τύπο επιλογής της σωστής μορφής. Τα αρχεία PO το δηλώνουν μέσω μιας κεφαλίδας Plural-Forms.
# 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() και gettext_lazy()
Παράλειψη εκτέλεσης του compilemessages
Το LOCALE_PATHS δεν έχει ρυθμιστεί
Απουσία του i18n_patterns από τα URL
Έξυπνη εναλλακτική επιλογή γλώσσας με το django-locale-chain
Το σύστημα μετάφρασης του Django χρησιμοποιεί απευθείας το LANGUAGE_CODE όταν λείπει μια περιφερειακή παραλλαγή. Ένας χρήστης με γλώσσα pt-BR βλέπει Αγγλικά ακόμη και όταν διαθέτετε μεταφράσεις pt-PT. Το django-locale-chain το διορθώνει εγκαθιστώντας αλυσίδες εναλλακτικής επιλογής στο gettext: για το pt-BR δοκιμάζεται το pt-PT και μετά το pt, προτού χρησιμοποιηθεί η προεπιλεγμένη γλώσσα σας.
# 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"]})Προτεινόμενη δομή έργου
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
Αφήστε εδώ το αρχείο μετάφρασής σας
JSON, YAML, PO, XML, CSV, Markdown, Properties
ή κάντε κλικ για να επιλέξετε αρχείο
Γλώσσες-στόχοι
Εναλλακτική επιλογή γλώσσας με το django-locale-chain
Όταν λείπει ένα κλειδί μετάφρασης από μια περιφερειακή γλώσσα όπως το pt-BR, το Django μεταβαίνει απευθείας στη γλώσσα του προτύπου αντί να ελέγξει πρώτα τη γονική γλώσσα pt.
pip install django-locale-chain# settings.py
LOCALE_CHAINS = {
'pt-BR': ['pt', 'es', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
}
MIDDLEWARE = [
...
'django_locale_chain.middleware.LocaleChainMiddleware',
...
]Δείτε τον οδηγό μας για την εναλλακτική επιλογή γλώσσας, όπου θα βρείτε την πλήρη λίστα των υποστηριζόμενων πλαισίων και των 75 ενσωματωμένων αλυσίδων. Learn more →