Reputation: 1
I could create i18n switcher for English and French below in Django following The set_language redirect view and this is how I set up translation(English and French) in Django. *I use Django 4.2.1:
# "core/settings.py"
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
path("my_app1/", include('my_app1.urls')),
)
urlpatterns += [
path("i18n/", include("django.conf.urls.i18n"))
]
# "templates/index.html"
{% load i18n %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}">
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go">
</form>
{% translate "Hello" %} {% trans "World" %}
Then, I can switch French to English as shown below:
And, I can switch English to French as shown below:
But, I don't know how to create it for Django Admin.
So, how can I create i18n switcher for Django Admin?
Upvotes: 1
Views: 517
Reputation: 184
you must override admin/base.html
and translate admin views by i18n_patterns
.
you can use this gist
Upvotes: 0
Reputation: 1
First, set up translation(English and French) following my answer.
Then, you need to create custom_admin.css
in core/static/core/admin/css/
and prepare usa_flag.png
and france_flag.png
in core/static/core/admin/images/
and create __init__.py
(Empty file) and i18n_switcher.py
in core/templatetags/
and copy base.html from django/contrib/admin/templates/admin/base.html
in your virtual environment to templates/admin/
as shown below:
django-project
|-core
| |-settings.py
| |-urls.py
| |-static
| | └-core
| | └-admin
| | |-css
| | | └-custom_admin.css # Here
| | └-images
| | |-usa_flag.png # Here
| | └-france_flag.png # Here
| └-templatetags
| |-__init__.py # Here
| └-i18n_switcher.py # Here
|-my_app1
| |-views.py
| |-urls.py
| |-models.py
| |_admin.py
| └-apps.py
|-my_app2
|-templates
| |-admin
| | └-base.html # Here
| └-index.html
└-locale
└-fr
└-LC_MESSAGES
|-django.po
└-django.mo
And, put the code below to custom_admin.css
:
/* "core/static/core/admin/css/custom_admin.css" */
img.i18n_flag {
width: 16px;
vertical-align: text-top;
}
And, put the code below to i18n_switcher.py
:
# "core/templatetags/i18n_switcher.py"
from django import template
from django.conf import settings
register = template.Library()
@register.simple_tag
def switch_i18n(full_path, prefix_lang):
lang_codes = [list[0] for list in settings.LANGUAGES]
if prefix_lang not in lang_codes:
raise Exception('%s is not a supported language code' % prefix_lang)
parts = full_path.split('/')
parts[1] = prefix_lang
return '/'.join(parts)
And, add <link ... 'core/admin/css/custom_admin.css' %}"/>
after <link ... "admin/css/base.css" %}{% endblock %}">
and add <a ...><img ... 'core/admin/images/usa_flag.png' %}"/></a> /
and <a ...><img ... 'core/admin/images/france_flag.png' %}"/></a> /
after {% block userlinks %}
as shown below:
{% "templates/admin/base.html" %}
...
<head>
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{% block stylesheet %}{% static "admin/css/base.css" %}{% endblock %}">
{% ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ %}
<link rel="stylesheet" type="text/css" href="{% static 'core/admin/css/custom_admin.css' %}"/>
...
<!-- Container -->
<div id="container">
...
<div id="header">
...
<div id="user-tools">
....
{% block userlinks %}
{% ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ %}
<a href="{% switch_i18n request.get_full_path 'en' %}">
<img class="i18n_flag" src="{% static 'core/admin/images/usa_flag.png' %}"/>
</a> /
{% ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ %}
<a href="{% switch_i18n request.get_full_path 'fr' %}">
<img class="i18n_flag" src="{% static 'core/admin/images/france_flag.png' %}"/>
</a> /
...
Now, you can switch French to English by clicking on USA flag as shown below:
And, you can switch English to French by clicking on France flag as shown below:
Actually, you can add your code <form ...></form>
after <div id="branding">...</div>
as shown below to create i18n switcher for English and French in Django Admin:
{% "templates/admin/base.html" %}
...
<!-- Container -->
<div id="container">
...
<div id="header">
<div id="branding">
{% block branding %}{% endblock %}
</div>
{% ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ Here ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ %}
<form action="{% url 'set_language' %}" method="post">{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}">
<select name="language">
{% get_current_language as LANGUAGE_CODE %}
{% get_available_languages as LANGUAGES %}
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
{{ language.name_local }} ({{ language.code }})
</option>
{% endfor %}
</select>
<input type="submit" value="Go">
</form>
Then, you can switch French to English as shown below:
And, you can switch English to French as shown below:
But, I prefer the 1st solution.
Upvotes: 0