This document covers three localization-related topics: Creating language files , locale aware date, time and numbers input/output in forms, and controlling localization in templates.

See also

The Using internationalization in your own projects document included with the Django HOW-TO documents collection.

How to create language files

Once the string literals of an application have been tagged for later translation, the translation themselves need to be written (or obtained). Here’s how that works.

Locale restrictions

Django does not support localizing your application into a locale for which Django itself has not been translated. In this case, it will ignore your translation files. If you were to try this and Django supported it, you would inevitably see a mixture of translated strings (from your application) and English strings (from Django itself). If you want to support a locale for your application that is not already part of Django, you’ll need to make at least a minimal translation of the Django core.

A good starting point is to copy the Django English .po file and to translate at least some translation strings.

Message files

The first step is to create a message file for a new language. A message file is a plain-text file, representing a single language, that contains all available translation strings and how they should be represented in the given language. Message files have a .po file extension.

Django comes with a tool, django-admin.py makemessages, that automates the creation and upkeep of these files.

A note to Django veterans

The old tool bin/make-messages.py has been moved to the command django-admin.py makemessages to provide consistency throughout Django.

Gettext utilities

The makemessages command (and compilemessages discussed later) use commands from the GNU gettext toolset: xgettext, msgfmt, msgmerge and msguniq.

Changed in Django 1.2: Please, see the release notes

The minimum version of the gettext utilities supported is 0.15.

To create or update a message file, run this command:

django-admin.py makemessages -l de

...where de is the language code for the message file you want to create. The language code, in this case, is in locale format. For example, it's pt_BR for Brazilian Portuguese and de_AT for Austrian German.

The script should be run from one of two places:

  • The root directory of your Django project.
  • The root directory of your Django app.

The script runs over your project source tree or your application source tree and pulls out all strings marked for translation. It creates (or updates) a message file in the directory locale/LANG/LC_MESSAGES. In the de example, the file will be locale/de/LC_MESSAGES/django.po.

By default django-admin.py makemessages examines every file that has the .html file extension. In case you want to override that default, use the --extension or -e option to specify the file extensions to examine:

django-admin.py makemessages -l de -e txt

Separate multiple extensions with commas and/or use -e or --extension multiple times:

django-admin.py makemessages -l de -e html,txt -e xml

When creating message files from JavaScript source code you need to use the special 'djangojs' domain, not -e js.

No gettext?

If you don't have the gettext utilities installed, django-admin.py makemessages will create empty files. If that's the case, either install the gettext utilities or just copy the English message file (locale/en/LC_MESSAGES/django.po) if available and use it as a starting point; it's just an empty translation file.

Working on Windows?

If you're using Windows and need to install the GNU gettext utilities so django-admin makemessages works see gettext on Windows for more information.

The format of .po files is straightforward. Each .po file contains a small bit of metadata, such as the translation maintainer's contact information, but the bulk of the file is a list of messages -- simple mappings between translation strings and the actual translated text for the particular language.

For example, if your Django app contained a translation string for the text "Welcome to my site.", like so:

_("Welcome to my site.")

...then django-admin.py makemessages will have created a .po file containing the following snippet -- a message:

#: path/to/python/module.py:23
msgid "Welcome to my site."
msgstr ""

A quick explanation:

  • msgid is the translation string, which appears in the source. Don't change it.
  • msgstr is where you put the language-specific translation. It starts out empty, so it's your responsibility to change it. Make sure you keep the quotes around your translation.
  • As a convenience, each message includes, in the form of a comment line prefixed with # and located above the msgid line, the filename and line number from which the translation string was gleaned.

Long messages are a special case. There, the first string directly after the msgstr (or msgid) is an empty string. Then the content itself will be written over the next few lines as one string per line. Those strings are directly concatenated. Don't forget trailing spaces within the strings; otherwise, they'll be tacked together without whitespace!

Mind your charset

When creating a PO file with your favorite text editor, first edit the charset line (search for "CHARSET") and set it to the charset you'll be using to edit the content. Due to the way the gettext tools work internally and because we want to allow non-ASCII source strings in Django's core and your applications, you must use UTF-8 as the encoding for your PO file. This means that everybody will be using the same encoding, which is important when Django processes the PO files.

To reexamine all source code and templates for new translation strings and update all message files for all languages, run this:

django-admin.py makemessages -a

Compiling message files

After you create your message file -- and each time you make changes to it -- you'll need to compile it into a more efficient form, for use by gettext. Do this with the django-admin.py compilemessages utility.

This tool runs over all available .po files and creates .mo files, which are binary files optimized for use by gettext. In the same directory from which you ran django-admin.py makemessages, run django-admin.py compilemessages like this:

django-admin.py compilemessages

That's it. Your translations are ready for use.

A note to Django veterans

The old tool bin/compile-messages.py has been moved to the command django-admin.py compilemessages to provide consistency throughout Django.

Working on Windows?

If you're using Windows and need to install the GNU gettext utilities so django-admin compilemessages works see gettext on Windows for more information.

.po files: Encoding and BOM usage.

Django only supports .po files encoded in UTF-8 and without any BOM (Byte Order Mark) so if your text editor adds such marks to the beginning of files by default then you will need to reconfigure it.

Creating message files from JavaScript source code

You create and update the message files the same way as the other Django message files -- with the django-admin.py makemessages tool. The only difference is you need to provide a -d djangojs parameter, like this:

django-admin.py makemessages -d djangojs -l de

This would create or update the message file for JavaScript for German. After updating message files, just run django-admin.py compilemessages the same way as you do with normal Django message files.

gettext on Windows

This is only needed for people who either want to extract message IDs or compile message files (.po). Translation work itself just involves editing existing files of this type, but if you want to create your own message files, or want to test or compile a changed message file, you will need the gettext utilities:

  • Download the following zip files from the GNOME servers http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one of its mirrors

    • gettext-runtime-X.zip
    • gettext-tools-X.zip

    X is the version number, we are requiring 0.15 or higher.

  • Extract the contents of the bin\ directories in both files to the same folder on your system (i.e. C:\Program Files\gettext-utils)

  • Update the system PATH:

    • Control Panel > System > Advanced > Environment Variables.
    • In the System variables list, click Path, click Edit.
    • Add ;C:\Program Files\gettext-utils\bin at the end of the Variable value field.

You may also use gettext binaries you have obtained elsewhere, so long as the xgettext --version command works properly. Do not attempt to use Django translation utilities with a gettext package if the command xgettext --version entered at a Windows command prompt causes a popup window saying "xgettext.exe has generated errors and will be closed by Windows".

Format localization

New in Django 1.2: Please, see the release notes

Django's formatting system is disabled by default. To enable it, it's necessary to set USE_L10N = True in your settings file.


The default settings.py file created by django-admin.py startproject includes USE_L10N = True for convenience.

When using Django's formatting system, dates and numbers on templates will be displayed using the format specified for the current locale. Two users accessing the same content, but in different language, will see date and number fields formatted in different ways, depending on the format for their current locale.

Django will also use localized formats when parsing data in forms. That means Django uses different formats for different locales when guessing the format used by the user when inputting data on forms.


Django uses different formats for displaying data to those it uses for parsing data. Most notably, the formats for parsing dates can't use the %a (abbreviated weekday name), %A (full weekday name), %b (abbreviated month name), %B (full month name), or %p (AM/PM).

To enable a form field to localize input and output data simply use its localize argument:

class CashRegisterForm(forms.Form):
   product = forms.CharField()
   revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)

Creating custom format files

Django provides format definitions for many locales, but sometimes you might want to create your own, because a format files doesn't exist for your locale, or because you want to overwrite some of the values.

To use custom formats, first thing to do, is to specify the path where you'll place format files. To do that, just set your FORMAT_MODULE_PATH setting to the path (in the format 'foo.bar.baz) where format files will exists.

Files are not placed directly in this directory, but in a directory named as the locale, and must be named formats.py.

To customize the English formats, a structure like this would be needed:


where formats.py contains custom format definitions. For example:


to use a space as a thousand separator, instead of the default for English, a comma.

Controlling localization in templates

When you have enabled localization using USE_L10N, Django will try to use a locale specific format whenever it outputs a value in a template.

However, it may not always be appropriate to use localized values -- for example, if you're outputting Javascript or XML that is designed to be machine-readable, you will always want unlocalized values. You may also want to use localization in selected templates, rather than using localization everywhere.

To allow for fine control over the use of localization, Django provides the l10n template library that contains the following tags and filters.

Template tags


New in Django 1.3: Please, see the release notes

Enables or disables localization of template variables in the contained block.

This tag allows a more fine grained control of localization than USE_L10N.

To activate or deactivate localization for a template block, use:

{% localize on %}
    {{ value }}
{% endlocalize %}

{% localize off %}
    {{ value }}
{% endlocalize %}


The value of USE_L10N is not respected inside of a {% localize %} block.

See localized and unlocalized for a template filter that will do the same job on a per-variable basis.

Template filters


New in Django 1.3: Please, see the release notes

Forces localization of a single value.

For example:

{{ value|localize }}

To disable localization on a single value, use unlocalize. To control localization over a large section of a template, use the localize template tag.


New in Django 1.3: Please, see the release notes

Forces a single value to be printed without localization.

For example:

{{ value|unlocalize }}

To force localization of a single value, use localize. To control localization over a large section of a template, use the localize template tag.