【问题标题】:how to serialize time with timezone in django-rest-framework's serializer?如何在 django-rest-framework 序列化程序中使用时区序列化时间?
【发布时间】:2020-08-23 15:38:35
【问题描述】:

我有一个 Django 模型:

class Clinic(models.Model):

    NAME_MAX_LENGTH = 150
    name = models.CharField(max_length=NAME_MAX_LENGTH,blank=False,null=False)
    start_at = models.DateTimeField(blank=False,default=timezone.now)

客户端将 start_at 字段作为带有时区的时间字段发送

{
 start_at : "12:40:10+04:30"
} 

我想将此时间字段转换为以当前日期为日期的 DateTimeField,然后将其作为可识别时区的 DateTimeField 保存到数据库中。

我想序列化这个字段并从输入中提取时区信息,然后创建我的 DateTimeField 对象。 如何在 rest_framework 序列化程序中做到这一点?

【问题讨论】:

    标签: python django datetime django-rest-framework django-timezone


    【解决方案1】:

    您可以为此创建一个自定义序列化器字段:

    import datetime
    
    from django.utils import timezone
    
    from rest_framework import serializers
    from rest_framework.fields import Field
    
    
    class TimeWithTimezoneField(Field):
    
        default_error_messages = {
            'invalid': 'Time has wrong format, expecting %H:%M:%S%z.',
        }
    
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
    
        def to_internal_value(self, value):
            value_with_date = datetime.datetime.now().strftime('%Y-%m-%d') + ' ' + value
            try:
                parsed = datetime.datetime.strptime(value_with_date, '%Y-%m-%d %H:%M:%S%z')
            except (ValueError, TypeError) as e:
                pass
            else:
                return parsed
            self.fail('invalid')
    
        def to_representation(self, value):
            if not value:
                return None
    
            if isinstance(value, str):
                return value
    
            return timezone.make_naive(value, timezone.utc).strftime("%H:%M:%S+00:00")
    
    
    class ClinicSerializer(serializers.ModelSerializer):
    
        start_at = TimeWithTimezoneField()
    
        class Meta:
            model = Clinic
            fields = [
                'id',
                'name',
                'start_at',
            ]
    
    

    在您的示例中,start_at: 12:40:10+04:30 将存储为时区感知日期时间(UTC 格式:08:40:10+00:00

    【讨论】:

      猜你喜欢
      • 2016-03-11
      • 2018-07-04
      • 1970-01-01
      • 2019-05-13
      • 2019-02-19
      • 2016-12-18
      • 2017-06-04
      • 1970-01-01
      • 2022-12-01
      相关资源
      最近更新 更多