Как показать дату и время в Джанго в определенном часовом поясе?

У меня есть проект Django (v1.10.6), в котором есть некоторые модели с полями даты и времени, например:

created_at = models.DateTimeField(auto_now_add=True)

которые хранятся в базе данных PostgreSQL без информации о часовом поясе:

created_at timestamp without time zone NOT NULL

postgresql.conf:

timezone = 'UTC'

Я хочу, чтобы все даты моего заявления были показаны в America/Bogota часовой пояс (он не должен зависеть от реального часового пояса пользователя), поэтому мой settings.py Файл имеет следующую конфигурацию:

TIME_ZONE = 'America/Bogota'
USE_I18N = False
USE_L10N = True
USE_TZ = True

SHORT_DATETIME_FORMAT = 'd-m-Y H:i:s'
SHORT_DATE_FORMAT = 'd-m-Y'
TIME_FORMAT = 'H:i:s'

но когда я пишу

{{ object.created_at|date:'SHORT_DATETIME_FORMAT' }}

в шаблонах он по-прежнему показывает дату в UTC формат.

Обновить:

Я добавил следующее промежуточное ПО, но это не помогло:

class TimezoneMiddleware(MiddlewareMixin):
    def process_request(self, request):
        timezone.activate(pytz.timezone(settings.TIME_ZONE))

Обновление 2:

Работает следующим образом:

import pytz
from django.utils import timezone

timezone.is_naive(object.created_at)  # True
object.created_at.replace(tzinfo=timezone.utc)

(заставляя дату быть в UTC часовой пояс, а затем передать его в шаблон без localize фильтр), но я не понимаю, почему Django по-прежнему возвращает наивные даты и времени, когда USE_TZ установлен в True,

5 ответов

Вы можете создать промежуточное ПО и использовать функцию активации для установки определенного часового пояса.

middleware.py

import pytz
import requests

from django.utils import timezone

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

def __call__(self, request):
    
    tzname = 'America/Bogota'
    if tzname:
        timezone.activate(pytz.timezone(tzname))
    else:
        timezone.deactivate()
    return self.get_response(request)

settings.py

MIDDLEWARE = [      ........
            'projectname.middleware.TimezoneMiddleware',
]

Вам необходимо выбрать текущий часовой пояс.

Вы должны установить текущий часовой пояс на фактический часовой пояс конечного пользователя с помощью activ (). В противном случае используется часовой пояс по умолчанию.

Некоторые соответствующие выдержки из документов ниже.

Часовой пояс по умолчанию - это часовой пояс, определенный настройкой TIME_ZONE.

Текущий часовой пояс - это часовой пояс, который используется для рендеринга.

Вы должны установить текущий часовой пояс на фактический часовой пояс конечного пользователя с помощью activ (). В противном случае используется часовой пояс по умолчанию.

От: https://docs.djangoproject.com/en/1.10/topics/i18n/timezones/

Я рекомендую иметь все datetimeхранится внутри UTC, поэтому настройка TIME_ZONE = 'UTC' в вашем settings.py и затем переключение текущего часового пояса на часовой пояс, в котором вы хотите выводить данные. Это значительно упростит добавление дополнительных часовых поясов позже и значительно упростит любую арифметику даты или времени, особенно если вам придется учитывать любые изменения летнего времени., Если вам это действительно не нужно, возможно, будет проще полностью отключить часовые пояса.

Попробуйте django-datetime-widget и используйте настройки:

Если вы хотите использовать локализацию:

  • Установите USE_L10N = True, USE_TZ = True и USE_I18N = True в settings.py
  • Добавьте 'django.middleware.locale.LocaleMiddleware' в MIDDLEWARE_CLASSES в settings.py
  • При создании виджета добавьте атрибут usel10n = True like: DateTimeWidget(usel10n=True)

Ссылка здесь:

https://github.com/asaglimbeni/django-datetime-widget

В файле settings.py

измените TIME_ZONE = 'Asia/Baghdad' на название часового пояса вашей страны.

Другие вопросы по тегам