14π
From the documentation:
Selecting the current time zone
The current time zone is the
equivalent of the current locale for translations. However, thereβs no
equivalent of the Accept-Language HTTP header that Django could use to
determine the userβs time zone automatically. Instead, Django provides
time zone selection functions. Use them to build the time zone
selection logic that makes sense for you.
You can try setting timezone cookie via javascript by utilizing getTimezoneOffset function or try to do some geoip magic and figure timezone by location. Probably the most reliable way would be to ask the user directly and save this information in user profile/session.
14π
Iβve simplified it even further, and you can plug in in here: https://github.com/Miserlou/django-easy-timezones
or
http://gun.io/blog/django-easy-timezones/
- Installing django 1.5(development version) in virtualenv
- How to combine django plus gevent the basics?
9π
I was hunting around for the sam thing yesterday. In the end I ended up putting together a Django app to what BluesRockAddict suggests above (i.e. use getTimezoneOffset):
https://github.com/adamcharnock/django-tz-detect
I hope someone finds that useful.
- How to print pretty JSON on a html page from a django template?
- Does Django have a way to open a HTTP long poll connection?
- How to override template in django-allauth?
- What are the disadvantages of using AWS ELB directly with Gunicorn (no nginx)?
- Make browser submit additional HTTP-Header if click on hyperlink
2π
There is a nice APP for django to activate timezone https://pypi.python.org/pypi/django-visitor-information-middleware/0.1.0. Which having two middleware
TimezoneMiddleware
The middleware activates a timezone for an authenticated user.
VisitorInformationMiddleware
This middleware adds the following keys to the request.visitor dictionary:
country β country the visitor is based in.
city β city the visitor is based in
location.timezone β timezone used in the location visitor is based in
location.unit_system β unit system used in the location visitor is based in
user.timezone β timezone of the currently authenticated user
user.unit_system β unit system of the currently authenticated user.
cookie_notice β True if a cookie consent notice should be displayed for the current visitor.
Note: Location of the user is determined based on the user's IP address.
- Django template indentation guideline
- Testing authentication in Django Rest Framework Views β Cannot authenticate when testing
2π
There are 2 ways without and with django-tz-detect to automatically detect and apply the userβs current timezone rather than applying only one timezone set to TIME_ZONE in settings.py
. *I recommend the way without django-tz-detect
and I use Django 4.2.3.
First, create middleware
folder with __init__.py
(Empty file) and custom.py
in core/
and copy base.html from django/contrib/admin/templates/admin/base.html
in your virtual environment to templates/admin/
as shown below. *You can see my answer explaining how to create middlewares and you can see my answer explaining how to set templates
folder and you can see my answer explaining how to override django admin templates:
django-project
|-core
| |-settings.py
| β-middleware # Here
| |-__init__.py
| β-custom.py
|-my_app1
|-my_app2
β-templates
|-my_app1
| β-base.html
|-my_app2
| β-base.html
β-admin
β-base.html # Here
<Without django-tz-detect
>
Now, put the code below to custom.py
:
# "core/middleware/custom.py"
import zoneinfo
from django.utils import timezone
from django.shortcuts import render
class TimezoneMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
tz = request.COOKIES.get("mytz")
if tz:
timezone.activate(zoneinfo.ZoneInfo(tz))
else:
timezone.activate(zoneinfo.ZoneInfo("UTC"))
return self.get_response(request)
Then, put <script></script>
just before </body>
in templates/my_app1/base.html
and templates/my_app2/base.html
as shown below:
{% "templates/my_app1/base.html" %}
{% "templates/my_app2/base.html" %}
<script>
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (!tz) {
tz = "UTC"
}
document.cookie = "mytz=" + tz + ";path=/";
</script>
</body>
Then, put <script></script>
just before </body>
tag in templates/admin/base.html
as shown below:
{% "templates/admin/base.html" %}
<script>
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (!tz) {
tz = "UTC"
}
document.cookie = "mytz=" + tz + ";path=/";
</script>
</body>
Finally, set TimezoneMiddleware
to MIDDLEWARE, then every time you load a django website, the userβs current timezone is automatically detected and applied:
# "core/settings.py"
MIDDLEWARE = [
...
'core.middleware.custom.TimezoneMiddleware'
]
<With django-tz-detect
>
Now, install django-tz-detect
as shown below:
pip install django-tz-detect
Then, set tz_detect
and TimezoneMiddleware
to INSTALLED_APPS and MIDDLEWARE
respectively in settings.py
as shown below. *Make sure that django.template.context_processors.request is set to TEMPLATESβs OPTIONSβs context_processors
:
# "core/settings.py"
INSTALLED_APPS = [
...
'tz_detect' # Here
]
MIDDLEWARE = [
...
'tz_detect.middleware.TimezoneMiddleware', # Here
]
...
TEMPLATES = [
{
...
'DIRS': [
BASE_DIR / 'templates'
],
...
'OPTIONS': {
'context_processors': [
...
'django.template.context_processors.request', # Here
...
],
},
},
]
Then, add the path below to urlpatterns
in core/urls.py
as shown below:
# "core/urls.py"
urlpatterns = [
path('admin/', admin.site.urls),
path('my_app1/', include('my_app1.urls')),
path('my_app2/', include('my_app2.urls')),
path('tz_detect/', include('tz_detect.urls')) # Here
]
Then, load tz_detect.py
, then use tz_detect
tag just before </body>
tag in templates/my_app1/base.html
and templates/my_app2/base.html
as shown below:
{% "templates/my_app1/base.html" %}
{% "templates/my_app2/base.html" %}
{% load tz_detect %}
...
{% tz_detect %}
</body>
Finally, load tz_detect.py
, then use tz_detect
tag just before </body>
tag in templates/admin/base.html
as shown below:
{% "templates/admin/base.html" %}
{% β Here β %}
{% load i18n static i18n_switcher tz_detect %}<!DOCTYPE html>
...
<!-- END SVGs -->
{% tz_detect %}
</body>
- Django i18n: how to not translate the admin site?
- Django; AWS Elastic Beanstalk ERROR: Your WSGIPath refers to a file that does not exist
- How do I reply to an email using the Python imaplib and include the original message?
- Ruby HAML with Django?
- Django BooleanField as a dropdown
1π
I currently created a middleware class (following Djangoβs documentation) in which I rely on MaxMind geoip database (http://dev.maxmind.com/geoip/legacy/geolite) and GeoDjango (https://docs.djangoproject.com/en/1.5/ref/contrib/gis/) to retrive userβs country code and then set the timezone dynamically using pytz:
class TimezoneMiddleware(object):
def __getUserTimeZone(self, request):
info = IPResolver(request).getGeoInfo()
return pytz.country_timezones[info['country_code']][0]
def process_request(self, request):
try:
tz = self.__getUserTimeZone(request)
timezone.activate(tz)
logger.debug('Time zone "%s" activated' % str(tz))
except Exception as e:
logger.error('Unable to set timezone: %s' % str(e))
pytz.country_timezones
returns a collection of time zones available for the given country, so I basically choose the first one returned.
IPResolver
is a personal utility class I wrote on top of django.contrib.gis.utils.GeoIP
0π
I just did this in my program. In my js:
<script>
var today = new Date()
var offset = today.getTimezoneOffset()
const serializedData = 'csrfmiddlewaretoken={{ csrf_token }}&tz_offset= '
+ offset.toString()
</script>
Then on the django side:
def your_function(request):
tz_offset = request.POST.get('tz_offset')
now = datetime.datetime.now() - timedelta(minutes=int(tz_offset))
return now
I pass the serializedData into the POST request and then access that in my function
<script>
function update_transaction(serializedData){
$.post('{% url "your_url" %}', serializedData, function(data){
//do stuff
});
}
</script>
- How to mock chained function calls in python?
- 'admin' is not a registered namespace in Django 1.4
- Django and Celery β ModuleNotFoundError: No module named 'celery.task'
- How to unit test methods inside django's class based views?
- Regular expression in URL for Django slug