~2 min read • Updated Mar 15, 2026
Introduction
Modern web applications often need to serve users from different countries, cultures, and language backgrounds. Django provides a powerful and comprehensive framework for internationalization (i18n) and localization (l10n), enabling developers to translate text, format dates and numbers, and adapt content to user preferences.
Django essentially does two things:
- Allows developers and template authors to mark parts of the application for translation or localization.
- Uses these markers to present content in the user’s preferred language and format.
Language preferences are typically provided by the browser via the Accept-Language header. Formatting (dates, numbers, etc.) depends on the target locale. Time zone detection, however, requires additional configuration because browsers do not send it automatically.
Internationalization vs Localization
These two terms are often confused, but Django treats them as distinct concepts:
Internationalization (i18n)
Preparing the software for localization. This includes marking strings for translation and structuring the application so it can support multiple languages. This is typically done by developers.
Localization (l10n)
Providing actual translations and locale-specific formats (dates, numbers, etc.). This is usually done by translators.
For deeper reading, see:
- W3C Web Internationalization FAQ
- Wikipedia’s article on internationalization
- GNU gettext documentation
Note: Django’s USE_I18N setting controls translation, even though it affects both internationalization and localization. The name is historical.
Key Terminology
Locale Name
A locale name identifies a specific language or a language-country combination. Formats:
- ll → language only (e.g.,
it,es) - ll_CC → language + country (e.g.,
de_AT,pt_BR,sr_Latn)
Rules:
- Language part → lowercase
- Country part → uppercase (2 letters) or TitleCase (longer)
- Separator → underscore
Language Code
Used by browsers in the Accept-Language header. Format is similar to locale names but uses a dash instead of an underscore:
itde-atpt-br
Language codes are case-insensitive.
Message File (.po)
A plain-text file containing translation strings and their translated versions for a specific language.
Each language has its own .po file.
Translation String
A literal string in your code or templates that can be translated using Django’s translation tools.
Format File
A Python module that defines locale-specific formatting rules for:
- dates
- times
- numbers
- currency formats
Conclusion
Django’s internationalization and localization framework makes it easy to build applications that adapt to users around the world. By understanding key concepts like locale names, language codes, message files, and translation strings, developers can create flexible, multilingual applications that feel natural to users in any region.
Written & researched by Dr. Shahin Siami