在Django Rest Framework中使用任意时区返回某些Django模型的DateTimeField
的pythonic方法是什么?
此刻,我的视图以UTC返回DateTime,因为据我所知,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, ...)
...
序列化器:
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对象,转换为不同的时区并在视图末尾再次格式化为字符串不是一个好主意?还有什么其他方法?
答案 0 :(得分:1)
您需要localtime()
才能获取当前时区的时间,因为now()
将始终以UTC返回时间,而与TIME_ZONE
的值无关。
您可以将任意时区传递给本地时间:
localtime(timezone='SOMETHING')
答案 1 :(得分:0)
我能够在任意时区获得时间戳,而无需解析datetime字符串,因为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
感谢Edgar R.Mondragón提到localtime()
及其用法。
答案 2 :(得分:0)
序列化器使用默认的TIME_ZONE,您可以在settings.py文件中设置
如果要为一个字段设置“时区”。
import pytz
class WeatherReportSerializer(serializers.ModelSerializer):
DatetimeValue = serializers.DateTimeField(default_timezone=pytz.timezone('Asia/Kolkata'))
class Meta:
model = ...
fields = [..., ..., ...]