Why I18N does not work when rendering API messages?

30 views Asked by At

I want to use i18n library in my views to return the API messages based on the accept language in headers. I have defined the below settings:

MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware', #  it must be put here
    'django.middleware.common.CommonMiddleware',
    ...
]
LANGUAGE_CODE = 'fa-IR' #  we want the default to be in farsi

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = False
from django.utils.translation import ugettext_lazy as _

#  settings for Internationalization (i18n) and localization
LANGUAGES = (
    ('fa', _('Persian')),
    ('en', _('English'))
)

DEFAULT_LANGUAGE = 1

# Contains the path list where Django should look into for django.po files
# for all supported languages..
LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'local'),
)

I have run the below command in the terminal to create .po files for translation:

python manage.py makemessages -l fa

This is its content. I have defined the msgstr for English messages on my own for when the Accept-Language is set as en, and also removed #, fuzzy from the file:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-24 12:37+0330\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <mailto:[email protected]>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: .\react\api_errors.py:5
msgid "مشکلی در نمایش اطلاعات نمودار زد-امتیاز مسافت پیش آمدهاست."
msgstr "An error has occured in distance Z-Score chart."

#: .\react\api_errors.py:6
msgid "مشکلی در نمایش اطلاعات نمودار زد-امتیاز زمان پیش آمدهاست."
msgstr "An error has occured in uptime Z-Score chart."

And this is my API:

# zscore for distance
@api_view(['GET'])
@admin_or_supervisor
def z_score_for_d_standard(request, user, device_id):
    try:
        lang_code = request.headers['Accept-Language']
    except Exception as e:
        print(e)
        traceback.print_exc()

    try:
        start_date = request.GET['start_date']
        end_date = request.GET['end_date']
    except Exception as e:
        print(e)
        traceback.print_exc()
        # GET YESTERDAY AND 30 DAYS BEFORE YESTERDAY DATE FROM FUNCTION (IMPORTED FROM TOOLS)
        start_date, end_date = get_last_thirty_days_start_and_end()

    try:
        if start_date in ['', None] or end_date in ['', None]:
            start_date, end_date = get_last_thirty_days_start_and_end()

        # superviser_doc = get_user_by_username(request.headers['Authorization'])
        customer_id = user['_source']['customer_id']
        # CREATE INSTANCE FROM DEVICEDAILY INTERFACE
        device_daily_interface = DeviceDailyDataInterface()

        # RETURN THESE PARAMETERS AS A DICT
        select_list = [DeviceDailyColumns.total_distance,
                    DeviceDailyColumns.timezone_date]

        data = device_daily_interface.filter(device_id=device_id,
                                            customer_id=customer_id,
                                            select_list=select_list,
                                            start_date=start_date, end_date=end_date,
                                            sort_field=DeviceDailyColumns.timezone_date,
                                            sort_type=SortType.asc,
                                            limit=5000)

        if len(data) <= 1:
            return Response([], status=status.HTTP_204_NO_CONTENT)

        distance_list = []
        date_list = []
        dates = set()
        days = []
        for row in data:
            date_string = row[DeviceDailyColumns.timezone_date]
            date_object = datetime.strptime(date_string, '%Y-%m-%dT%H:%M:%S.%fZ')
            day_of_date = date_object.strftime('%A')
            if date_string not in dates:
                distance_list.append(round(row[DeviceDailyColumns.total_distance]))
                date_list.append(date_string.split('T')[0])
                dates.add(date_string.split('T')[0])
                days.append(day_of_date)

        zscore = z_score(distance_list)

        data_dict = chart_standard_format('z-score', x=date_list, y=zscore, z=distance_list, w=days)
        return Response(data_dict['data'])

    except Exception as e:
        print(e)
        traceback.print_exc()
        code, message, status_code = ErrorCodes.Z_SCORE_DISTANCE_GENERAL_ERROR.value
        return Response({'message': message, 'code': code}, status=status.HTTP_400_BAD_REQUEST)

I have defined all my messages in a separate .py file in an Enum class like this:

from enum import Enum
from django.utils.translation import ugettext_lazy as _


class ErrorCodes(Enum):
    Z_SCORE_DISTANCE_GENERAL_ERROR = (1000, _("مشکلی در نمایش اطلاعات نمودار زد-امتیاز مسافت پیش آمده‌است."), 400)
    Z_SCORE_UPTIME_GENERAL_ERROR = (1010, _("مشکلی در نمایش اطلاعات نمودار زد-امتیاز زمان پیش آمده‌است."), 400)

And I pass the Accept-Language like this in headers while calling the APIs:

Accept-Language: en
or
Accept-Language: fa

But every time it just shows the Persian text...And it seems that translation does not work at all... How can I fix this issue?

0

There are 0 answers