ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • django translator
    Project using python/Cloning Airbnb 2021. 3. 7. 19:14

    django translator란?

      django app을 여러 언어로 번역할 수 있는 기능을 제공한다.

    Make locale

    settings.py

     

      먼저 locale folder를 생성한다. 그리고 settings.py에서 해당 경로를 설정한다.

    # config/settings.py
    
    LOCALE_PATHS = (BASE_DIR / "locale",)

    {% trans %}

      static은 무시하고 중요한 것은 i18n이다. i18n은 internatialization으로 i와 n 사이에 있는 18개라는 뜻이다. SW 국제화를 뜻한다. i18n은 load로 불러온다. 여기서 {% trans %}와 {% blocktrans %}를 사용할 수 있다.

    번역을 하고 싶은 문자열을 {% trans %}로 감싼다.

    {% blocktrans %}

      만약 번역을 하고 싶은데 변수가 있다면 {% blocktrans %}로 감싼다. blocktrans with 뒤에 넘겨줄 key=value를 만든다. 여러 개의 key 값을 넘겨주고 싶으면 뛰어쓰기를 하면 된다.
    (예를 들어, {% blocktrans with guests=room.guets beds=room.beds %} 식으로 말이다.) blocktrans tag 안에서 python code로 {{guets}}같이 사용하면 된다.

      blocktrans는 변수를 넘겨주는 경우 이외에도 문장 순서를 고칠 때도 사용한다. 영어는 "주+동+목" 이지만 우리는 "주+목+동"이기 때문이다.

    translate python code

      models.py의 일부분이다. python code에서 번역을 하고 싶은 부분은 gettext_lay를 사용한다. 대부분의 string을 감싸줘야 하기 때문에 gettext_lazy로 길게 하지 않고 'as _' 를 사용해서 (_)로 감싸준다.

    # users/models.py
    
    from django.utils.translation import gettext_lazy as _
    
    class User(AbstractUser):
    
        """ Custom User model """
    
        GENDER_MALE = "Male"
        GENDER_FEMALE = "Female"
        GENDER_OTHER = "Other"
        GENDER_CHOICES = (
            (GENDER_MALE, _("Male")),
            (GENDER_FEMALE, _("Female")),
            (GENDER_OTHER, _("Other")),
        )
    
        LANGUAGE_KOREAN = "KR"
        LANGUAGE_ENGLISH = "EN"
        LANGUAGE_CHOICES = (
            (LANGUAGE_KOREAN, _("Korean")),
            (LANGUAGE_ENGLISH, _("English")),
        )

    commands

      $ django-admin makemessages --locale=ko

      위 명령어로 template에서 trans 혹은 blocktrans로 감싼 string으로 .po file을 만든다. 뒤에 옵션으로 locale을 붙여줘야 하고 locale에는 번역을 하고자 하는 language code를 줘야 한다. 나는 한국어를 줄 것이므로 ko 값을 줬다. 위 명령어를 사용하면 locale folder 안에 .po file이 생성될 것이다.

      msgid는 trans로 감싼 string이고 msgstr은 내가 번역한 string이다. .po file을 생성하면

    #: .\templates\base.html:27
    msgid "Searching By City"
    msgstr ""
    
    #: .\templates\pages\rooms\room_detail.html:48
    #, python-format
    msgid "%(guests)s guests"
    msgstr ""
    
    #: .\users\models.py:21
    msgid "Male"
    msgstr ""
    
    #: .\users\models.py:22
    msgid "Female"
    msgstr ""
    
    #: .\users\models.py:23
    msgid "Other"
    msgstr ""

      이런 식으로만 생성되고 ""에 내가 번역을 써줘야 한다. blocktrans에 %(guets)s 처럼 뒤에 s가 하나 붙는데 신경쓰지 말고 번역에서도 붙여주자.

    translated tempalte
    translated python code

      번역이 완료 되었다면 compile을 해줘야 한다. 명령어는 다음과 같다.

      $ django-admin compilemessages

       내가 편집한 .po file을 compile하면 .mo file이 생성된다. 이제 해야할 작업은 language code에 따라 영어나 한국어로 언제든 변환하는 작업을 해야 한다.

    Switch language

    settings.py

      LocaleMiddleware는 django가 여러 가지 언어들 중 하나를 선택할 때 추가해줘야 하는 middleware다.

      settings.py에 빨간색 박스가 추가되어야 한다. django 3.1.7 version 기준으로 SessionMiddleware와 CommonMiddleware는 추가되어 있다. LocaleMiddleware만 저 사이에 추가하면 된다. 왜 저 사이에 추가해야 하는지는 django docs가 그러라고 했다.

      그리고 settings.py에 LANGUAGE_COOKIE_NAME을 "django_language"로 초기화 한다. 옛날에 내가 만들 때 2.2.5 version에서는 없어도 됬는데 3.17 version에서는 필요하다. LOCALE_PATHS는 위 글에서 선언했으니 패스~

    translator.js

      translator.js라는 파일을 생성하고 gulp를 통해서 transcompile을 해서 main.js로 만들었다. 자세한 내용은 git source code를 보면 알 수 있다.

    // assets/js/translator.js
    
    const jsLang = document.getElementById("js-lang");
    const handleChange = () => {
      const selected = jsLang.value;
      fetch(`/users/switch-language?lang=${selected}`).then(() =>
        window.location.reload()
      );
    };
    jsLang.addEventListener("change", handleChange);
    
    // base.html
    
    <script src="{% static 'js/main.js' %}"></script>

    footer.html

    users/urls.py

    from django.urls import path
    from . import views
    
    app_name = "users"
    
    urlpatterns = [
        path("switch-language", views.switch_language, name="switch-language")
    ]
    

    views.py

      2 가지 version의 code가 있다. django==3.1.7 version 기준으로는 LANGUAGE_COOKIE_NAME을 사용해야 한다.

    # django == 2.2.5 version code
    
    from django.utils import translation
    from django.http import HttpResponse
    
    def switch_language(request):
        lang = request.GET.get("lang", None)
        if lang is not None:
            request.session[translation.LANGUAGE_SESSION_KEY] = lang
        return HttpResponse(status=200)
    # django == 3.1.7 version code
    
    from django.http import HttpResponse
    from config import settings
    
    def switch_language(request):
        lang = request.GET.get("lang", None)
        if lang is not None:
            response = HttpResponse(200)
        print(settings.LANGUAGE_COOKIE_NAME)
        response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)
        print(settings.LANGUAGE_COOKIE_NAME)
        return response

    결과

    영어

    한국어

      trans

    참고 자료

    소스 코드

    github.com/zpskek/airbnb-clone-v3/commit/92d6489dfcfb62995db6ae534a1b52004c20d00a

    'Project using python > Cloning Airbnb' 카테고리의 다른 글

    django create room by FBV  (0) 2021.03.08
    django Http404()  (0) 2021.03.08
    django session  (0) 2021.03.06
    django room detail by CBV  (0) 2021.03.06
    django room detail by FBV  (0) 2021.03.06

    댓글

Designed by Tistory.