Kun yi wa strings alama don fassara, kun samar da fayilolin .po, kun gudanar da compilemessages, kuma aikace-aikacen ku har yanzu yana nuna Turanci. Ba ku kaɗai ba ne. Tsarin i18n na Django yana da ƙarfi, amma yana da gefuna masu kaifi waɗanda suke kama ko masu ƙwarewa a cikin developers.
Wannan jagora ya ƙunshi dalilai 10 mafi yawan da suke sa fassarar Django ta gaza a shiru, tare da alamomin da ke faruwa da kuma gyara ga kowane ɗaya.
1. Mantuwar Gudanar da compilemessages Bayan Gyara Fayilolin .po
Kun gyara fayil .po (da hannu ko tare da kayan aiki), amma rubutun da aka fassara bai taɓa bayyana ba. Aikace-aikacen yana ci gaba da nuna asalin strings na Turanci.
Django ba ya karanta fayilolin .po a lokacin aiki. A maimakon haka yana karanta fayilolin binary na .mo (machine object) da aka tattara. Idan kun gyara fayil .po ba tare da sake tattarawa ba, Django ba ya san wani abu ya canja ba.
Gudanar da compilemessages bayan kowane canjin fayil .po:
python manage.py compilemessages
Idan kuna sarrafa fassarar ku ta atomatik tare da TranslateBot, ƙara compilemessages a matsayin mataki na ƙarshe a cikin aikin ku:
python manage.py makemessages -a --no-obsolete
python manage.py translate
python manage.py compilemessages
2. Rashin {% load i18n %} a cikin Templates
Kuna amfani da {% trans "Hello" %} a cikin template, amma Django yana jefa TemplateSyntaxError. Ko mafi muni, tag ɗin a shiru baya yin komai idan kuna da injin template da ba a saita daidai ba.
Tags ɗin {% trans %} da {% blocktrans %} suna cikin ɗakin karatu na tag template i18n na Django. Ba tare da loda shi ba, injin template ba zai gane su ba.
Ƙara {% load i18n %} a saman kowane template da ke amfani da tags na fassara:
{% load i18n %}
<h1>{% trans "Welcome to our site" %}</h1>
<p>{% blocktrans with name=user.name %}Hello, {{ name }}!{% endblocktrans %}</p>
Wannan buƙata ce ta kowane template. Ko da template na iyaye ya loda i18n, templates na yara waɗanda ke amfani da tags na fassara suna buƙatar bayyanar {% load i18n %} nasu.
3. LocaleMiddleware Ba Ya Cikin MIDDLEWARE ko Yana Matsayi Maras Kyau
Django kullum yana ba da abun ciki a cikin yaren tsoho ba tare da la'akari da header Accept-Language na browser, prefix na URL, ko saitunan zaman ba.
LocaleMiddleware yana ƙayyade yaren da ke aiki ga kowane buƙata. Ba tare da shi ba, Django yana komawa ga LANGUAGE_CODE kuma ya yi watsi da duk hanyoyin zaɓar yare. Matsayinsa a cikin tarin middleware ma yana da muhimmanci, domin yana buƙatar damar shiga bayanan zaman da warware URL.
Ƙara LocaleMiddleware zuwa saitunan MIDDLEWARE ku, bayan SessionMiddleware da CommonMiddleware:
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.locale.LocaleMiddleware", # Must be after SessionMiddleware
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
]
Ku tabbata django.conf.urls.i18n an haɗa shi cikin saitunan URL ku idan kuna amfani da canjin yare ta URL:
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
path("", include("myapp.urls")),
)
4. Rashin Daidaiton Lambar Yare (misali pt-br vs pt_BR)
Fassarori sun wanzu a cikin fayilolin .po ku, compilemessages ya yi nasara, amma Django ya yi watsi da fassara ga wasu locale.
Django yana sa ran directories na locale su bi tsarin <language>_<COUNTRY> tare da mai raba underscore da lambar ƙasa babban harafi. Misali, pt_BR don Fotigal na Brazil. Idan directory ɗin ku an sanya masa suna pt-br, pt-BR, ko ptBR, Django ba zai same shi ba. Haka kuma ga saitunan LANGUAGES: lambobin a can suna amfani da hyphens (pt-br), amma tsarin fayiloli yana amfani da underscores (pt_BR).
Tabbatar tsarin directory ku ya dace da abin da Django ke tsammanin:
locale/
pt_BR/
LC_MESSAGES/
django.po
django.mo
Kuma a cikin saitunan ku, yi amfani da tsarin hyphen:
LANGUAGES = [
("en", "English"),
("pt-br", "Brazilian Portuguese"),
("zh-hans", "Simplified Chinese"),
]
Lokacin gudanar da makemessages, yi amfani da tsarin underscore don tutar locale:
python manage.py makemessages -l pt_BR
5. Shigarwar Fuzzy da Aka Tsallake a Shiru Yayin Tattarawa
Fassara ta wanzu a cikin fayil .po, amma Django yana nuna asalin string na Turanci a lokacin aiki don wannan shigarwar musamman. Wannan yana da ban takaici musamman domin fassarar tana nan a cikin fayil ɗin.
Lokacin da makemessages na Django ya gano string na tushe ya canja kaɗan, yana sanya alamar fassarar da ke akwai a matsayin "fuzzy" (ma'ana hasashe ne da ke buƙatar nazarin ɗan adam). Umarnin compilemessages yana tsallake duk shigarwar fuzzy, yana ɗaukar su a matsayin ba a fassara ba. Don haka shigarwar ta yi kama da aka fassara a cikin fayil .po, amma fayil .mo ya cire ta gaba ɗaya.
Shigarwar fuzzy tana kama da haka:
#, fuzzy
msgid "Welcome to our website!"
msgstr "Welkom op onze website!"
Sake duba fassarar, sabunta msgstr idan ya dace, sannan cire tutar #, fuzzy:
msgid "Welcome to our website!"
msgstr "Welkom op onze website!"
Sannan sake tattarawa:
python manage.py compilemessages
A cikin aikin da ya fi girma, shigarwar fuzzy suna taruwa kuma suna sauƙin rasa. Umarnin check_translations na TranslateBot yana kama waɗannan ta atomatik:
python manage.py check_translations
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 3 fuzzy
CommandError: Translation check failed
Ƙara check_translations --makemessages zuwa bututun CI ku kuma ba za ku taɓa aika shigarwar fuzzy ba.
6. LOCALE_PATHS Ba a Saita Ba ko Yana Nuni Zuwa Directory Maras Kyau
makemessages yana samar da fayilolin .po a wuri ɗaya, amma Django yana neman su a wani wuri. Fassarori sun wanzu a kan disk amma ba a taɓa loda su ba.
Django yana neman fayilolin fassara a cikin tsari na musamman: directories na LOCALE_PATHS da farko, sannan directory locale/ na kowane aikace-aikace, kuma a ƙarshe directory locale/ na aikin. Idan ba a saita LOCALE_PATHS ba ko yana nuni zuwa hanyar da ba daidai ba, Django ba zai taɓa samun fayilolin .po ku ba.
Saita LOCALE_PATHS a cikin saitunan ku zuwa hanyar cikakke:
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
LOCALE_PATHS = [
BASE_DIR / "locale",
]
Tabbatar directory ɗin yana nan kuma yana ɗauke da tsarin da ake tsammani:
locale/
de/
LC_MESSAGES/
django.po
django.mo
nl/
LC_MESSAGES/
django.po
django.mo
Kuskure na yau da kullum shi ne saita LOCALE_PATHS zuwa locale/ (na dangi) maimakon hanyar cikakke. Django ba ya warware hanyoyin dangi daga tushen aikin ku. Ya dogara ga directory na aikin tsari, wanda sau da yawa ba abin da kuke tsammani ba ne.
7. Cache Yana Ba da Fassarar Tsoho
Kun sabunta kuma kun tattara fassarori, amma rubutun tsoho yana ci gaba da bayyana. Sake kunna uwar garke yana gyara shi.
Bayanan fassarar Django ana loda su sau ɗaya ga kowane tsari. A cikin samarwa, uwar garken WSGI/ASGI kamar Gunicorn ko Uvicorn suna ci gaba da rike tsarin ma'aikata na dogon lokaci. Fayil .mo na iya canjawa a kan disk, amma tsarin da ke gudana har yanzu yana da fassarar tsoho a cikin ƙwaƙwalwar ajiya. Bugu da ƙari, idan kuna amfani da tsarin cache na Django ko reverse proxy kamar Nginx ko Cloudflare, amsoshin da aka cache za su ba da abun ciki na tsoho har sai sun ƙare.
Sake kunna uwar garken aikace-aikacen ku bayan aika sabbin fassarori:
# Gunicorn
kill -HUP $(cat /tmp/gunicorn.pid)
# Systemd
sudo systemctl restart myapp
# Docker
docker compose restart web
Don tsarin cache na Django, share cache bayan sabunta fassarori:
from django.core.cache import cache
cache.clear()
A cikin ci gaba, runserver yana sake loda ta atomatik lokacin da fayilolin Python suka canja amma ba ya lura da fayilolin .mo. Kuna buƙatar sake kunna shi da hannu bayan gudanar da compilemessages.
8. Strings da Ba a Nannaɗe Cikin gettext ba (_() ko {% trans %})
makemessages ba ya fitar da wasu strings, don haka ba sa taɓa bayyana a cikin fayilolin .po ku kuma ba a taɓa fassara su ba. Wannan shine matsalar mafi sauƙi kuma mafi sauƙin rasa a cikin babban codebase.
Umarnin makemessages na Django yana amfani da xgettext don bincika lambar tushe ku don alamomin fassara. Idan ba a nannaɗe string a cikin gettext() (yawanci ana ba da sunan _()), gettext_lazy(), {% trans %}, ko {% blocktrans %} ba, ba a ganuwa ga tsarin fitarwa.
Nannaɗe kowane string da ke fuskantar mai amfani:
# Python code
from django.utils.translation import gettext_lazy as _
class Article(models.Model):
class Meta:
verbose_name = _("article")
verbose_name_plural = _("articles")
# Views
from django.utils.translation import gettext as _
def my_view(request):
message = _("Your changes have been saved.")
return HttpResponse(message)
<!-- Templates -->
{% load i18n %}
<h1>{% trans "Welcome" %}</h1>
<p>{% blocktrans with count=items|length %}You have {{ count }} items.{% endblocktrans %}</p>
Yi amfani da tutar --dry-run na TranslateBot don ganin strings da ba a fassara ba a halin yanzu, don ku iya kama strings da aka rasa yayin fitarwa:
python manage.py translate --target-lang de --dry-run
Wannan yana nuna duk shigarwar da ba a fassara ba a cikin fayilolin .po ku ba tare da yin wani kiran API ko canje-canje ba.
9. f-strings Ba Za a Iya Fassara Su Ba (Iyakar Django)
Kun nannaɗe f-string a cikin _() kuma kun sami kuskuren syntax, ko makemessages ya fitar da string da ya lalace/ɓangare wanda ba za a iya fassara ba.
f-strings na Python ana kimanta su a lokacin aiki. Kayan aikin fitarwa xgettext yana nazarin lambar tushe a tsaye, don haka ba zai iya kimanta maganganu na Python a cikin {} ba. Wannan yana nufin _(f"Hello, {name}") ana fitar da shi a matsayin string da ke ɗauke da maganar zahiri {name} (ko ya gaza fitarwa gaba ɗaya), kuma shigarwar .po da ta haifar ba za ta taɓa dacewa da string na lokacin aiki ba.
Yi amfani da tsarin % na Django ko .format() tare da placeholders masu suna a maimakon haka:
# Wrong -- f-string cannot be extracted
message = _(f"Hello, {user.name}! You have {count} new messages.")
# Correct -- named placeholders
message = _("Hello, %(name)s! You have %(count)d new messages.") % {
"name": user.name,
"count": count,
}
# Also correct -- .format() with positional args
message = _("Hello, {0}! You have {1} new messages.").format(user.name, count)
Wannan ba iyakar TranslateBot ko kayan aiki ba ne. Asali ne na yadda gettext ke aiki. String na tushe dole ne ya kasance literal mai tsayi don a iya fitar da shi kuma a neme shi a lokacin aiki.
TranslateBot yana kiyaye duk waɗannan tsarin placeholder (%(name)s, {0}, %s, tags na HTML) yayin fassara, don haka strings da aka fassara sun ci gaba da aiki cikakke.
10. Kuskuren Format String na Placeholder da Ke Lalata Tattara .po
compilemessages ya gaza tare da kuskure, ko fayil .po yana da rashin daidaiton tutar #, python-format, kuma an jefar da shigarwar a shiru.
Lokacin da string na tushe ya ƙunshi placeholders na tsarin Python kamar %(name)s, Django yana sanya alamar shigarwar .po da #, python-format. Idan fassarar tana da placeholders daban-daban (kuskuren rubutu kamar %(nome)s, placeholder da ya ɓace, ko ƙarin) kayan aikin gettext na iya ƙin shigarwar ko compilemessages na iya gaza. Wannan yawanci yana faruwa da fassarar hannu ko tare da kayan aikin fassarar AI waɗanda ba su fahimci ma'anar placeholder ba.
Shigarwa da ta lalace tana kama da haka:
#, python-format
msgid "Hello, %(name)s! You have %(count)d new messages."
msgstr "Hallo, %(naam)s! Je hebt %(count)d nieuwe berichten."
A nan %(naam)s ya kamata ya zama %(name)s. Placeholders dole ne su dace da tushen daidai.
Tabbatar strings da aka fassara sun ƙunshi ainihin placeholders kamar na tushen. Duba kuskuren rubutu, placeholders da suka ɓace, da ƙarin placeholders.
Wannan shine yankin da TranslateBot ke ba da fa'ida na gaske. Dabararsa ta kiyaye placeholder tana tabbatar cewa duk tsarin format strings (%(name)s, {0}, %s) a cikin abin da aka fitar da fassara sun dace da tushen daidai. Ana rufe sarrafa placeholder da 100% gwajin rufewa, don haka kuskuren format string daga fassara ana kawar da su a matakin kayan aiki maimakon a kama su a lokacin tattarawa.
Idan kuna fassara da hannu ko da kayan aiki da ba ya sarrafa placeholders, tabbatar da fayilolin .po ku tare da:
msgfmt --check-format locale/de/LC_MESSAGES/django.po
Wannan yana gudanar da tabbatarwar tsarin format string na gettext kuma yana ba da rahoto kan duk wani rashin daidaituwa.
Haɗa Duka: Hanyar Aiki ta Kariya
Yawancin waɗannan matsaloli suna raba musabbabin tushe ɗaya: matakai na hannu waɗanda suke sauƙin mantawa. Ga hanyar aiki da ke hana duk matsaloli 10:
# 1. Extract strings (catches #8 -- any new gettext-wrapped strings)
python manage.py makemessages -a --no-obsolete
# 2. Translate (catches #1, #5, #8, #9, #10 -- handles untranslated,
# fuzzy, and placeholder issues automatically)
python manage.py translate
# 3. Compile (catches #1 -- generates .mo files)
python manage.py compilemessages
# 4. Verify in CI (catches everything that slipped through)
python manage.py check_translations --makemessages
Ƙara mataki na 4 zuwa bututun CI ku kuma strings da ba a fassara ba, shigarwar fuzzy, da kuskuren tsari za su sa ginin ya gaza kafin ya isa samarwa.
Jadawalin Nuni Mai Sauri
| Musabbabi | Alama | Gyara Layi Ɗaya |
|---|---|---|
Babu compilemessages |
Fassarori sun wanzu amma ba sa bayyana | python manage.py compilemessages |
Babu {% load i18n %} |
TemplateSyntaxError kan {% trans %} |
Ƙara {% load i18n %} zuwa template |
| Babu LocaleMiddleware | Yare kullum ya koma Turanci | Ƙara django.middleware.locale.LocaleMiddleware zuwa MIDDLEWARE |
| Rashin daidaiton lambar yare | Ba a sami directory na locale ba | Yi amfani da pt_BR (underscore) don directories, pt-br (hyphen) don saituna |
| An tsallake shigarwar fuzzy | Fassara a cikin .po amma ba a cikin app |
Cire tutar #, fuzzy bayan dubawa |
| LOCALE_PATHS ba daidai ba | Fayilolin .po sun wanzu amma Django ya yi watsi |
Saita LOCALE_PATHS zuwa hanyar cikakke |
| Fassarar da aka cache | Rubutun tsoho ya bayyana bayan sabuntawa | Sake kunna uwar garken aikace-aikace |
| String ba a cikin gettext ba | String ya ɓace daga fayilolin .po |
Nannaɗe a cikin _() ko {% trans %} |
| f-string a cikin gettext | Fitarwa ta lalace ko rashin daidaituwa a lokacin aiki | Maye gurbin tare da placeholders % ko .format() |
| Rashin daidaiton placeholder | compilemessages ya gaza ko an jefar da shigarwa |
Daidaita placeholders daidai tsakanin tushe da fassara |
Yawancin waɗannan matsaloli suna ɓacewa lokacin da kuka sarrafa matakin fassara ta atomatik kuma ku tilasta dubawa a cikin CI. Umarnin translate na TranslateBot yana sarrafa kiyaye placeholder da fassara ta hankali, yayin da check_translations ke kama duk abin da ya kuɓuce (shigarwar da ba a fassara ba, tutocin fuzzy, da matsalolin format string) kafin su isa samarwa.