What is Django?
Django is a Python-based web development framework that ranks in the top 10 in popularity and is used by 14.65% of developers (according to the StackOverflow survey). Such popularity is explained by the vast pool of tasks that Django can handle, its large and active community, extensive documentation, and continuous growth and support. The framework's abilities allow the following:
- Database management (ORM (Object-Relational Mapping, migrations.)
- Web application development (dynamic websites, URL routing, etc.)
- User and content management
- Security and compliance handling
- Etc.
Moreover, Django has robust internationalization and localization support, enabling developers to create inclusive and globally accessible applications. With the Django i18n (internationalization) framework, the tech team can:
- Easy mark the text for translation;
- Fast generate the files for translation;
- Detect the language preferred for the user and switch to the needed version;
- Automatically format dates, times, and numbers according to the user's locale.
All these Django abilities make it one of the best choices for multilingual application development and support. Scroll down to learn more about the top practices of Django i18n and l10n (localization).
Setting up the development environment for Django
To start with a Django internationalization, let's get our Django development environment up and running. Just follow the steps below:
Step 1. Prerequisites
We assume that Python is installed on our PC since it is a must-have for Django development. If you still need to do that, don't worry! Follow this step-by-step guide: Download and Install Python 3 Latest Version - GeeksforGeeks to get the latest version.
Next, we recommend creating a virtual environment using the virtualenv package to keep your project's dependencies separate from others and activate it. Once you activate the virtual environment, you will see a change in your terminal prompt, letting you know your setup is ready!
Step 2. Install Django
With the virtual environment activated, install Django using pip:
pip install django
Verify the installation by running:
django-admin --version
Step 3. Create a new Django project Run the command below and the new directory will be visible within your Django folder:
django-admin startproject myproject
Now, you can open the new directory, named myproject, using any code editor you prefer; in our case, it is VS (Visual Studio). The structure for myproject will be the following:
Navigate to the project directory using the command:
cd myproject
To verify everything works correctly, start the server
py manage.py runserver
Copy the IP address from the command prompt to a web browser to view the initial landing page, confirming that Django has been successfully installed and we are ready to proceed.
Every Django application we create comprises a Python package that adheres to a set of rules. Django can automatically generate an app's fundamental directory structure, allowing you to write code instead of managing folders.
To enable it to be imported as a distinct top-level module, we will create our i18n app in the same directory as our manage.py file in this tutorial (ensure you're in the same directory as manage.py)
Type this command:
py manage.py startapp i18n
Then, inside the project's home directory, we will see the app folder. This directory structure will host the i18n application.
Also, we can see the i18n folder inside VS.
Open the settings.py file in the myproject directory and add the app name to the INSTALLED_APPS section.
At myproject folder, open the file urls.py and put the following code in it: (Note that in purple color is what we added)
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('i18n.urls', namespace='i18n'))
]
In Django, the term "URLconfs" refers to the modules that help us map URL patterns to views. While this might be a familiar concept for Django developers, it’s good to clarify it for everyone! When we use the include() function, Django removes the portion of the URL that matches up until that point and then passes the remaining string to the included URLconf for further processing. If you want to dive deeper into URLconfs, check out the official Django documentation for more details!
Navigate to the app folder (i18n) and make the following changes in views.py:
from django.shortcuts import render
from django.utils.translation import gettext as _
# Create your views here.
def home (request):
welcomeMessage= _('Welcome to this Django Internationalization Guide!')
return render(request,'home.html', {'trans': welcomeMessage})
This is the most basic view in Django. To invoke this view, we must map it to a URL, which requires a URLconf.
To create a URLconf in the i18n directory, create a file called urls.py. The app directory should look like this:
i18n/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
urls.py
views.py
The i18n/urls.py file includes the code below:
from django.urls import path
from . import views
app_name = 'i18n'
urlpatterns = [
path('', views.home, name='Welcome to this Django Internationalization Guide!'),
]
We made a new folder named template in the i18n app folder. Afterward, a new file named home.html is created inside the template folder:
In this HTML file, we can build our first homepage by following code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Django i18n</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
</head>
<body>
{{trans}}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>
Now that we have connected a home view to the URLconf, verify its functionality with the command:
python manage.py runserver
When we open our development server in the browser, we should see the text "Welcome to this Django Internationalization Guide!" displayed, as defined in the home view.
Let’s edit the myproject's settings.py file to finish the procedure. We navigate through the settings.py file and find the MIDDLEWARE section. There, we add the following code:
django.middleware.locale.LocaleMiddleware
⚠️ Be careful with position of this line of code. It should be placed between 'django.contrib.sessions.middleware.SessionMiddleware' and 'django.middleware.common.CommonMiddleware',
Now, we need to let Django know which languages our project will support by setting the LANGUAGES list. We'll also tell it where to find our translation files (PO files) using LOCALE_PATHS, and don’t forget to set up our static files too.
Setting up Django for i18n
As we mentioned at the start, Django simplifies the internationalization process with its built-in support for i18n. Let's overview its internationalization features in more detail:
- Language files and translations: Django allows teams to translate the application into multiple languages using .po files, which store the translations for the text in our application. Developers can generate and manage these translations using Django's makemessages and compilemessages commands.
- Locale Middleware automatically detects the user's preferred language from the browser or session and serves the site in that language if a translation is available.
- Translating text in templates: Django provides template tags like {% trans %} and {% blocktrans %} to mark text for translation in HTML templates.
Example:
{% trans "Welcome to our website!" %}
- Translating strings in Python code: Developers can mark strings for translation using gettext or ugettext (for Unicode strings). Example: from django.utils.translation import gettext as _message = _("This is a translatable message.")
- Formatting dates, numbers, and timezones: Django automatically formats dates, times, and numbers based on the user's locale, displaying them in a familiar way.
How to enable i18n in Django?
In Django, translation and supporting multiple languages are controlled by the USE_I18N setting. This setting activates i18n features but also involves localization l10n, making the application more adaptable to different languages and regional preferences.
Let’s ensure that we have activated internationalization and localization in our configuration. To do this, we must make the following changes to myproject/settings.py and confirm the following settings are configured to enable internationalization and localization.
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
These settings enable internationalization and localization support and specify where the locale files are stored. Before diving into the main part of the translation and localization process, let’s take a moment to define some key terms that will ensure we’re all on the same page.
- Locale name —The code for a language (ll) or language-country combination (ll_CC), such as it (Italian) or pt_BR (Brazilian Portuguese)
- Language code — tells the browser which languages can be used in the browser Accept-Language headers, like it, de-at, or pt-br. Codes are case-insensitive and separated by a dash.
- Message file — is a plain-text file with a .po file extension that contains language translation strings.
- Translation string — text that is translated.
- Format file — Python module that specifies data formats for a locale.
⚠️ Before continuing with the creation of the Translation files, be careful to have gettext tools installed in your OS.
If you are using Windows, visit this link gettext 0.21 and iconv 1.16 - Binaries for Windows | mlocati - Michele Locati and based on your operating system, 32 or 64, continue with the static version.
How to create the Django translation files?
Django uses .po files for translations. To create translation files for specific locales, follow these steps (in our example we will create the folders for de (German) and fr (French) languages:
- In the i18n app folder, create locale folder containing two subfolders
- de for German language
- fr for French language
Generate Messages:
Navigate to the project directory and run:
py manage.py makemessages -all
This command creates directories for German (de) and French (fr) under the locale directory, containing .po files where translations will be stored.
Now we have the following structure:
Edit .po Files:
Open the django.po files located in locale/de/LC_MESSAGES/ and locale/fr/LC_MESSAGES/ to add your translations.
Our chosen django i18n example of translation are:
#: .\i18n\views.py:6
msgid "Welcome to this Django Internationalization Guide!"
msgstr "Willkommen zu diesem Django-Internalisierungshandbuch!"
AND
msgid "Welcome to this Django Internationalization Guide!"
msgstr "Bienvenue dans ce guide d'internalisation de Django!"
Compile Messages:
After adding translations, compile the messages using:
py manage.py compilemessages
This command generates .mo files, which Django uses at runtime to serve the translated content.
We are able to restart the server to see if everything works as expected after implementing the necessary changes. On our home view, the results that follow will be visible to us:
This one represents DE language.
This one represents FR language.
Both of these screenshots depict the successful implementation of internationalization in our Django web application.
How can Lingohub help with localizing the Django file?
When we talk about Django file translation and localization, finding a solution that can easily handle the Django file format (.po) and provide a seamless translation experience for the team is essential.
We want to show you how convenient Lingohub is, and you can try it yourself for all the benefits with our 14-day trial. Sign up, and let's translate your Django application together.
Step 1. Synchronize your repository with Lingohub
To simplify file import/export, Lingohub provides a list of integrations and REST APIs that reduce manual file transfer. Let's take a look at how this works with integrations.
- First of all, set up a new project on Lingohub. Ensure that your project platform is “Gettext PO.”
⚠️ Heads up! Once the project is created, the platform can’t be changed.
- Then, let’s connect Lingohub to our code repository (in our case it is GitHub, but you can use GitLab, Azure, Bitbucket). By doing this, we can effortlessly back and forth all translation files. Choose the needed plugin and make adjustments.
Read the support article to do this synchronization → Lingohub Integrations
- To make sure everything is perfectly aligned between GitHub and Lingohub, set up the Git plugin.
Let's stop for a moment to look at some of the Git plugin abilities - specifically resource filters and branching.
Resource filters enhance project management in Lingohub in several ways:
- Control over synchronization: they define which resources, such as GitHub/GitLab files, etc., should be synchronized.
- Tailored synchronization: You can specify the paths for resources, like directories, files, or web pages, ensuring that only the most relevant materials are synced to our project.
- Enhanced organization: By filtering out unnecessary resources, you can maintain a tidy project environment, making it easier for the team to locate important content.
If you want to dive deeper into this feature, continue to read here → What is it resource filters?
Branching is a tool that allows you to work with the different parts of the project (Git branches) and keep the main code clean. The branching feature allows the following:
- Switch seamlessly between different versions of the project. This means you can translate different parts without any hassle.
- Maintain a clean project: One of the best parts about using branches is that it helps keep our entire project organized. We can work on separate translations independently without risking any changes to the main content.
- Facilitate parallel workflows by allowing the translation team to work in parallel with the development team.
More information about the branching feature can be found in our Help Center → How to use branching in Lingohub?
Step 2. Import files to Lingohub
To import files, the first thing we want to do is find the synchronization icon at the top of the page. The system will usually default to the branch we have set in our plugin settings, but if we need to pull from a different branch, no worries! We can easily choose the one we need. Next, take a moment to select the specific files and languages we want to import. This way we will only bring in relevant content to our current localization efforts.
Once we have made our choices, just hit the “Pull” button, and voilà! Everything will be imported into Lingohub.
Step 3. Translate your files with Lingohub
To demonstrate how to work with the localization files, we will use the pre-translation feature, which can translate all the content with the machine translation engines in seconds. Of course, there are additional features in Lingohub that speed up the translation process - termbase, style guide, quality checks, translation memory, etc., but in this guide, we focus more on working with Django files, so that the pre-translation will be the best option. (Of course you can translate all your segments manually.)
→ Simply follow the steps outlined in our How to set up the pre-translation feature?
After the translation is complete, we will have a side-by-side comparison of the English-German, and English-French texts. This makes it super easy to review everything and make any adjustments as needed.
French translation
German translation
Step 4. Export data from Lingohub to the repository
To export data from Lingohub back to GitHub, start by clicking the synchronization icon at the top of the page once again.
We have two options:
- Push directly to the repository;
- Create a pull request (PR), which is the best way to collaborate with your team. It proposes changes while keeping everyone in the loop, making it easier to review and track modifications together.
A friendly reminder: while the direct push is quicker, it can sometimes lead to errors or conflicts, especially if we are working with a team. After we have decided on our push type, we select the specific files and languages we want to export, just like we did when importing data. Finally, once everything looks good and we are happy with our selections, we click the “Push” button to send our updates back to GitHub.
Conclusion
By following this guide, we have successfully set up internationalization in our Django project, managed translation files, and integrated with Lingohub for efficient translation workflows. This enables us to reach a broader audience by providing a localized experience adapted to different languages and regions. The internationalization of our Django app ensures that it reaches a global audience, providing a better user experience for non-English speakers. By adhering to these steps, we can prepare our Django app for international markets.
If you have any questions and want to learn more, please contact us or book a demo with our team!