Как вернуть DateTime в другом часовом поясе из сериализатора Django Rest Framework - PullRequest
0 голосов
/ 12 декабря 2018

Каков питонный способ возврата DateTimeField некоторой модели Django, использующей произвольный часовой пояс в Django Rest Framework?

В настоящий момент мое представление возвращает DateTime в UTC, потому что, насколько я знаю, Django хранит даты и время в часовых поясах как даты в UTC.

Модели:

class TimezoneMixin(models.Model):
    TIMEZONES = [(i, i) for i in country_timezones['ru']]

    timezone = models.CharField(choices=TIMEZONES, ...)

    class Meta:
        abstract = True

    def get_timezone(self):
        if self.timezone:
            return timezone(self.timezone)
        return get_current_timezone()


class Organization(TimezoneMixin, models.Model):
    ...

class Event(models.Model):
    organization = models.ForeignKey(Organization, ...)
    date_created = models.DateTimeField(auto_now_add=True, ...)
    ...

Serializer:

class EventSerializer(serializers.ModelSerializer):

    class Meta:
        model = Event
        fields = ('organization', 'date_created', ...)

В ViewSet я заполняю данные следующим образом

organization_id = ...  # Some logic to get required organization_id

data = {
    'date_created': timezone.now(), # django.utils.timezone
    'organization': organization_id,
    ...
}

serializer = EventSerializer(data=data)
if serializer.is_valid():
    serializer.save()
    response_data = serializer.data.copy()
    # Some logic to rename one of the keys in response data
    ...
    return Response(response_data, ...)  # rest_framework.response.Response

Даже если я заменю timezone.now() на что-то вроде timezone.now().astimezone(organization.get_timezone()), я все равно получу UTC DateTime в ответ.

Правильно ли я считаю, что разбирать date_created строку из response_data, создавать из нее объект DateTime, преобразовывать в другой часовой пояс и снова форматировать как строку в конце представления не очень хорошая идея?Каковы другие способы?

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Мне удалось получить метку времени в произвольном часовом поясе без разбора строки даты и времени, потому что serializer обеспечивает доступ к сохраненному instance.Итак, ниже мое решение

response_data = serializer.data.copy()
# Some logic to rename one of the keys in response data
...
event_date_created_utc = serializer.instance.date_created
# Basically calls get_timezone on Organization instance and returns the result
organization_timezone = get_timezone_by_organization_id(organization_id)
response_data['date_created'] = timezone.localtime(event_date_created_utc,
                                                   timezone=organization_timezone).isoformat()
return Response(response_data, ...)  # rest_framework.response.Response

Спасибо Эдгару Мондрагону за упоминание localtime() и его использование.

0 голосов
/ 12 декабря 2018

Вам нужно localtime(), чтобы получить время в текущем часовом поясе, поскольку now() всегда будет возвращать время в UTC независимо от значения TIME_ZONE.

. Вы можетепередать произвольный часовой пояс по местному времени:

localtime(timezone='SOMETHING')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...