Thiết lập website đa ngôn ngữ với Django

Nó sử dụng bộ công cụ gettext GNU để tạo và quản lý một tệp văn bản thuần túy đại diện cho một ngôn ngữ được gọi là message file . Tệp message kết thúc bằng .po làm phần mở rộng của nó. Một tệp khác được tạo cho mỗi ngôn ngữ sau khi bản dịch hoàn tất, tệp này kết thúc bằng phần mở rộng .mo . Đây được gọi là bản dịch đã biên dịch.

Cài đặt Gettext

Hãy bắt đầu bằng cách cài đặt bộ công cụ gettext .

Trên macOS, bạn nên sử dụng Homebrew :

$ brew install gettext
$ brew link --force gettext

Đối với hầu hết các bản phân phối Linux, nó được cài đặt sẵn. Và cuối cùng, đối với Windows, các bước cài đặt bạn có thể tham khảo tại đây . Hoặc tải trực tiếp file cài đặt tại đây.

Bật I18N (i18n) và L10N

Hãy kiểm tra xem các cài đặt sau đã được bật trong tệp settings.py chưa. Nếu chưa hãy bật nó.

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

Cài đặt đầu tiên là LANGUAGE_CODE . Theo mặc định, nó được đặt thành United States English (en-us). Đây là tên theo ngôn ngữ cụ thể. Hãy cập nhật nó thành một tên chung, tiếng Anh (en).

LANGUAGE_CODE = 'en'

Để LANGUAGE_CODE có hiệu lực, phải có USE_I18N=True , điều này cho phép hệ thống dịch của Django.

Các cài đặt còn lại:

  1. 'UTC'TIME_ZONE mặc định .
  2. USE_L10N được đặt thành True , Django sẽ hiển thị số và ngày tháng bằng cách sử dụng định dạng của ngôn ngữ hiện tại.
  3. Cuối cùng, khi USE_TZTrue , datetimes sẽ nhận biết múi giờ.

Hãy thêm một số cài đặt bổ sung để bổ sung cho những cài đặt hiện có:

from django.utils.translation import gettext_lazy as _

LANGUAGES = [
    ('vi', _('Vietnamese')),
    ('en', _('English')),
]
  • Chỉ định các ngôn ngữ mà bạn muốn cho dự án của mình. Nếu không, Django sẽ cho rằng dự án của bạn phải có sẵn ở tất cả các ngôn ngữ được hỗ trợ.
  • Cài đặt LANGUAGE này bao gồm mã ngôn ngữ và tên ngôn ngữ. Nhớ rằng các mã ngôn ngữ có thể theo ngôn ngữ cụ thể, chẳng hạn như vi-vn hoặc chung chung như vi.

Thêm django.middleware.locale.LocaleMiddleware vào danh sách cài đặt MIDDLEWARE. Phần mềm trung gian này nên đặt sau SessionMiddlewareLocaleMiddleware nhu cầu sử dụng dữ liệu phiên. Nó cũng nên được đặt trước CommonMiddlewareCommonMiddleware cần ngôn ngữ hoạt động để giải quyết các URL được yêu cầu. Do đó, thứ tự ở đây là rất quan trọng.

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',  # sau SessionMiddleware, trước CommonMiddleware
    'corsheaders.middleware.CorsMiddleware',  
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'corsheaders.middleware.CorsPostCsrfMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "django_htmx.middleware.HtmxMiddleware",
]

Thêm thư mục đường dẫn ngôn ngữ cho ứng dụng của bạn, nơi các tệp tin sẽ được lưu:

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale/'),
)

Bạn cần tạo thư mục locale bên trong dự án gốc của mình và thêm một thư mục mới cho mỗi ngôn ngữ:

locale
├── en
└── vi

Chạy lệnh sau từ thư mục dự án của bạn để tạo tệp tin nhắn .po cho mỗi ngôn ngữ:

django-admin makemessages --all --ignore=env
# or
django-admin makemessages --ignore="static" --ignore=".env"  -l vi

Lưu ý:

  • --all : tạo bản dịch cho tất cả ngôn ngữ
  • --ignore=... bỏ qua và không quét thư mục
  • -l vi : Chỉ tạo bản dịch cho ngôn ngữ vi

Bây giờ bạn nên có (với --all):

locale
├── en
│   └── LC_MESSAGES
│       └── django.po
└── vi
    └── LC_MESSAGES
        └── django.po

Trong một tệp messages .po :

  1. msgid : đại diện cho chuỗi dịch khi nó xuất hiện trong mã nguồn.
  2. msgstr : đại diện cho bản dịch ngôn ngữ, theo mặc định là trống. Bạn sẽ phải cung cấp bản dịch thực tế cho bất kỳ chuỗi nhất định nào.

Bạn có thể dịch bằng cách chỉnh sửa tệp .po từ trình chỉnh sửa mã thông thường của mình. Đối với mỗi trường msgstr mục trong thư mục vi, hãy nhập từ tương ứng trong tiếng Việt theo cách thủ công. Tuy nhiên, bạn nên sử dụng trình chỉnh sửa được thiết kế riêng cho .po như Poedit .

Xem thêm: Dịch Django trong trang quản trị Admin với Rosetta

Sau khi đã dịch xong trong tệp .po hãy chạy lệnh sau để bản dịch có hiệu lực:

django-admin compilemessages --ignore=env

Một tập tin .mo đã được tạo ra cho mỗi ngôn ngữ:

locale
├── en
│   └── LC_MESSAGES
│       ├── django.mo
│       └── django.po
└── vi
    └── LC_MESSAGES
        ├── django.mo
        └── django.po

Dịch Templates, Models và Form

Bạn có thể dịch các trường tên và biểu mẫu của Models bằng cách đánh dấu chúng để dịch bằng cách sử dụng hàm gettext hoặc gettext_lazy:

Chỉnh sửa tệp /models.py như sau:

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

class Product(models.Model):
    title = models.CharField(_('title'), max_length=90)
    description = models.TextField(_('description'))
    date = models.DateField(_('date'))
    price = models.DecimalField(_('price'), max_digits=10, decimal_places=2)

    def __str__(self):
        return self.title
django-admin makemessages --all --ignore=env

Vui lòng cập nhật msgstr bản dịch cho tiếng Việt hoặc ngôn ngữ cảu bạn theo cách thủ công hoặc sử dụng giao diện Poedit, sau đó biên dịch

django-admin compilemessages --ignore=env

Chúng tôi cũng có thể làm điều này cho các biểu mẫu (Form) bằng cách thêm nhãn (label).

Ví dụ:

from django import forms
from django.utils.translation import gettext_lazy as _

class ExampleForm(forms.Form):
    first_name = forms.CharField(label=_('first name'))

Để dịch các templates, Django cung cấp các thẻ {% trans %}{% blocktrans %} để dịch các chuỗi. Bạn phải thêm {% load i18n %} vào đầu tệp HTML để sử dụng các thẻ dịch.

Các thẻ {% trans %} cho phép bạn đánh dấu một từ để dịch. Django chỉ đơn giản là thực thi chức năng gettext trên văn bản đã cho trong nội bộ.

Các thẻ {% trans %} rất hữu ích cho các chuỗi dịch đơn giản, nhưng nó không thể xử lý nội dung cho
chuỗi dịch bao gồm các biến.

Mặt khác thẻ {% blocktrans %} cho phép bạn đánh dấu nội dung bao gồm các ký tự và biến.

Cập nhật phần tử sau trong tệp /templates/index.html để xem phần tử này hoạt động:

{% load i18n %}
<h1>{% trans "Welcome to Aznet.io" %}</h1>

Đừng quên thêm {% load i18n %} vào đầu tệp.

django-admin makemessages --all --ignore=env

Cập nhật các msgstr bản dịch sau :

# locale/vi/LC_MESSAGES/django.po

msgid "Welcome to Aznet.io"
msgstr "Chào mừng đến với Aznet.io"

Biên dịch các tin nhắn:

django-admin compilemessages --ignore=env