DRF序列化器保存数据时日期字段自动变更问题求助
问题排查:DRF Serializer时间与PostgreSQL存储不一致
现象
使用Django REST Framework保存数据时,serializer.data中last_date_time显示为'2023-03-01T00:00:00+04:00',但PostgreSQL数据库中该字段实际存储为'2023-02-28 20:00:00'。
相关代码
打印的serializer.data输出
[OrderedDict([('last_price', '62.63'), ('name', None), ('country', None), ('sector', None), ('industry', None), ('ticker', 'VUSA'), ('high_price', 62.7075), ('last_date_time', '2023-03-01T00:00:00+04:00')])]
数据库存储值
2023-02-28 20:00:00
View的create方法
def create(self, request, *args, **kwargs): if self.request.user.is_superuser: serializer = self.get_serializer(data=request.data, many=isinstance(request.data, list)) serializer.is_valid(raise_exception=True) print(serializer.data) self.perform_create(serializer) return Response({"Status": "We should be done"})
模型代码
class UsStockPriceModel(models.Model): ticker = models.CharField(max_length=30, blank=False, db_index=True) name = models.CharField(max_length=150, blank=True, null=True) # mainly for US stocks country = models.CharField(max_length=100, blank=True, null=True) sector = models.CharField(max_length=100, blank=True, null=True) industry = models.CharField(max_length=100, blank=True, null=True) last_price = models.FloatField(blank=True, null=True) high_price = models.FloatField(blank=True, null=True) last_date_time = models.DateTimeField(db_index=True) created_at = models.DateTimeField(auto_now_add=True)
序列化器代码
class UsStockPriceSerializer(serializers.ModelSerializer): last_price = serializers.CharField(required=False, allow_null=True, allow_blank=True) name = serializers.CharField(required=False, allow_null=True, allow_blank=True) # mainly for US stocks country = serializers.CharField(required=False, allow_null=True, allow_blank=True) sector = serializers.CharField(required=False, allow_null=True, allow_blank=True) industry = serializers.CharField(required=False, allow_null=True, allow_blank=True) class Meta: model = UsStockPriceModel fields = '__all__' def validate_last_price(self, value): if not value: return None try: return float(value) except ValueError: raise serializers.ValidationError('Valid integer is required')
问题原因
这是Django与PostgreSQL在时区处理上的正常行为:
- Django默认开启时区支持(
USE_TZ = True),会将传入的带时区的datetime转换为UTC时间存储到PostgreSQL中。2023-03-01T00:00:00+04:00转换为UTC就是2023-02-28 20:00:00,和数据库存储值完全一致。 serializer.data输出的是经过Django时区配置转换后的本地时间(对应TIME_ZONE设置的时区,此处为+4时区),所以显示的是转换后的时间。
解决方案
根据需求选择以下方式:
- 如果希望数据库存储和serializer输出一致,且不需要UTC存储:在
settings.py中设置USE_TZ = False,同时确保TIME_ZONE设置为你需要的时区(如'Asia/Dubai'对应+4时区)。注意:关闭时区支持可能引发其他时区相关问题,需谨慎评估。 - 如果需要保持UTC存储,但希望serializer输出UTC时间:修改序列化器,为
last_date_time指定DateTimeField并设置时区参数:last_date_time = serializers.DateTimeField(format='iso-8601', default_timezone='UTC') - 确认
settings.py中的TIME_ZONE配置是否正确,确保和你预期的时区一致。
内容的提问来源于stack exchange,提问作者Sid
相关产品推荐
相关产品推荐

