Django i18n get_language_info_list and get_available_languages provide different language code

With {% get_current_language as CURRENT_LANGUAGE %} , {{ CURRENT_LANGUAGE }} shows nl-nl

With {% get_available_languages as AVAILABLE_LANGUAGES %} , {{ AVAILABLE_LANGUAGES }} shows [('nl-NL', 'Nederlands'), ('en', 'Engels')]

With {% get_language_info_list for AVAILABLE_LANGUAGES as LANGUAGES %} , {{ LANGUAGES }} shows [{'bidi': False, 'code': 'nl', 'name': 'Dutch', 'name_local': 'Nederlands', 'name_translated': 'Nederlands'}, {'bidi': False, 'code': 'en', 'name': 'English', 'name_local': 'English', 'name_translated': 'Engels'}]

Settings:

# https://docs.djangoproject.com/en/dev/ref/settings/#language-code
LANGUAGE_CODE = "nl-NL"

# https://docs.djangoproject.com/en/dev/ref/settings/#languages
LANGUAGES = [
    ('nl-NL', _('Dutch')),
    ('en', _('English')),
]

In {{ LANGUAGES }} I expect code to be nl-NL and not nl. Anyone that can explain this discrepancy?

Django version: Django==4.2.10

Only nl is present in django/django/conf/locale. Based on LANG_INFO (from django.conf.locale import LANG_INFO). I found it is happening here generic_lang_code = lang_code.split("-")[0]:

def get_language_info(lang_code):
    from django.conf.locale import LANG_INFO

    try:
        lang_info = LANG_INFO[lang_code]
        if "fallback" in lang_info and "name" not in lang_info:
            info = get_language_info(lang_info["fallback"][0])
        else:
            info = lang_info
    except KeyError:
        if "-" not in lang_code:
            raise KeyError("Unknown language code %s." % lang_code)
        generic_lang_code = lang_code.split("-")[0]
        try:
            info = LANG_INFO[generic_lang_code]
        except KeyError:
            raise KeyError(
                "Unknown language code %s and %s." % (lang_code, generic_lang_code)
            )

    if info:
        info["name_translated"] = gettext_lazy(info["name"])
    return info
Back to Top