[PYTHON] Give Django users Language and Timezone settings to dynamically switch languages and time display

Thing you want to do

this

I want the user to set the language and timezone

Django fans, Django (greetings).

We are familiar with Django's support for I18N and L10N. And you know that it's very easy to harness those powers.

Just specify * LANGUAGE_CODE * as * USE_I18N = True * if you need multilingual translation, * USE_L10N = True * if you need format localization, * TIMEZONE * as * USE_TZ = True * if you want to match the timezone. ..

Then, you can create a global application just by asking Google Translate or DeepL Translator to create a translation file. If you're building an application using Django, you can quickly build an application with international expansion in mind.

But there is a problem.

If you made an app with international expansion in mind, and if it was used by Japanese, Americans, French, and Asian countries, where should you switch the language setting?

Yes, ** settings.py **. However, if you mess with the * LANGUAGE_CODE * settings, Django will finally output in the specified language. If * LANGUAGE_CODE * is set to * ja *, Django will display it in Japanese to each person in each country. In that case, it becomes difficult to understand what the internationalization was for.

Personally, this isn't strange, but the Django standard doesn't allow users to change even the Timezone settings, let alone Language. This time it's about allowing users to change it themselves.

How it works

About LANGUAGE

The basic code is excerpt from django's manual. Pass the language you want to use to * translation.activate * and set the value in the cookie. Now you can only switch the language that Django uses during this session.

from django.conf import settings
from django.http import HttpResponse
from django.utils import translation
user_language = 'fr'
translation.activate(user_language)
response = HttpResponse(...)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user_language)

This time for the user model

About TIME ZONE

The basic code is excerpt from django's manual. Pass the timezone you want to use to * timezone.activate *.

import pytz

from django.utils import timezone

class TimezoneMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        tzname = request.session.get('django_timezone')
        if tzname:
            timezone.activate(pytz.timezone(tzname))
        else:
            timezone.deactivate()
        return self.get_response(request)

Based on these codes, the rest is to customize the user model to provide fields for language and timezone settings, which you can change yourself.

That's why I prepared django-user-g11n.

django-user-g11n

django-user-g11n prepares Django's custom user model, inherits "TimeZoneAndUserLanguageSupportMixin" to give the user model * language * and * timezone *, and is set using Middleware. Dynamically change the language and time zone.

By the way, g11n is an abbreviation for (Globalization) and refers to I18n + L10N.

How to use

Before, if you want to try the sample immediately, please refer to "Using the sample".

First, install Django and django-user-g11n.

$ pip install django django-user-g11n

Then start your project with django-admin.py.

$ django-admin.py startproject example

Next, create a custom user model. For convenience, the application name is * accounts *.

$ manage.py startapp accounts

Once you've created your app, modify * accounts / models.py * to add a custom user model. At that time, it inherits * UserLanguageSupportMixin * and * UserTimeZoneSupportMixin *.

from django.contrib.auth import models as auth_models
from user_g11n.models import UserLanguageSupportMixin, UserTimeZoneSupportMixin


class User(UserTimeZoneSupportMixin,
           UserLanguageSupportMixin,
           auth_models.AbstractUser):
    pass

Next is the modification of * settings.py *.

Changes to settings.py

Add the app for the custom user model created this time and user-g11n to * INSTALLED_APPS *.

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    .
    .
    .
    'accounts',  # Your Custom user model application
    'user_g11n', # Add
)

Then modify MIDDLEWARE to add * UserLanguageMiddleware * and * UserTimeZoneMiddleware *.

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    .
    .
    .
    'user_g11n.middleware.UserLanguageMiddleware', # Add
    'user_g11n.middleware.UserTimeZoneMiddleware', # Add
]

Then specify AUTH_USER_MODEL to enable the custom user model.

AUTH_USER_MODEL = 'accounts.User'

Next, set I18N, L10N, TZ, and TIME_ZONE respectively.

USE_I18N = True

USE_L10N = True

USE_TZ = True

TIME_ZONE = "Asia/Tokyo" # Change to your local timezone

When the change is completed, perform migration and create a DB.

$ ./manage.py makemigrations && ./manage.py migrate

That's it. After that, create a superuser and change the language and time zone on the user management screen to switch the display in real time.

Use the sample

This Django app is being developed on GitHub.

Have the project cloned

$ docker-compose up

After that, you can try the sample app by accessing [http: // localhost: 8000](http: // localhost: 8000).

Summary

--Django's Internationalization Organization is the best ――I think you should prepare this from the beginning. Why not ... ――Django Oji loves Django. ――This year (2020), Django Congress has disappeared due to the influence of Covid-19, but it is being held in our hearts! almost every day···!

that's all

Recommended Posts

Give Django users Language and Timezone settings to dynamically switch languages and time display
django timezone and language settings
Display the time in Django according to the user's region (UTC)
I tried to illustrate the time and time in C language
I tried to display the time and today's weather w