Django Friday Tips: Timezone per user

Adding support for time zones in your website, in order to allow its users to work using their own timezone is a “must” nowadays. So in this post I’m gonna try to show you how to implement a simple version of it. Even though Django’s documentation is very good and complete, the only example given is how to store the timezone in the users session after detecting (somehow) the user timezone.

What if the user wants to store his timezone in the settings and used it from there on every time he visits the website? To solve this I’m gonna pick the example given in the documentation and together with the simple django-timezone-field package/app implement this feature.

First we need to install the dependency:

 $ pip install django-timezone-field==2.0rc1

Add to the INSTALLED_APPS of your project:

INSTALLED_APPS = [
    ...,
    'timezone_field',
    ...
]

Then add a new field to the user model:

class User(AbstractUser):
    timezone = TimeZoneField(default='UTC'

Handle the migrations:

 $python manage.py makemigration && python manage.py migrate

Now we will need to use this information, based on the Django’s documentation example we can add a middleware class, that will get this information on every request and set the desired timezone. It should look like this:

from django.utils import timezone


class TimezoneMiddleware():
    def process_request(self, request):
        if request.user.is_authenticated():
            timezone.activate(request.user.timezone)
        else:
            timezone.deactivate()

Add the new class to the project middleware:

MIDDLEWARE_CLASSES = [
    ...,
    'your.module.middleware.TimezoneMiddleware',
    ...
]

Now it should be ready to use, all your forms will convert the received input (in that timeone) to UTC, and templates will convert from UTC to the user’s timezone when rendered. For different conversions and more complex implementations check the available methods.

About the author

Gonçalo Valério

Software developer and owner of this blog. More in the "about" page.

View all posts