come serializzare l'ora con il fuso orario nel serializzatore di django-rest-framework?

Aug 24 2020

Ho un modello 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)

il client invia il campo start_at come campo orario con fuso orario simile

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

Voglio convertire questo campo dell'ora nel DateTimeField con la data corrente come data e quindi salvarlo nel database come DateTimeField che riconosce il fuso orario.

Voglio serializzare questo campo ed estrarre le informazioni sul fuso orario dall'input, quindi creare il mio oggetto DateTimeField. Come posso farlo nel serializzatore rest_framework?

Risposte

2 Charlesthk Aug 23 2020 at 23:50

Puoi creare un campo serializzatore personalizzato per questo:

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',
        ]

Con il vostro esempio, start_at: 12:40:10+04:30saranno conservati come un fuso orario datetime consapevoli (in UTC: 08:40:10+00:00)