Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
229 views
in Technique[技术] by (71.8m points)

python - How to show and use only days in datetime in DRF model fields and send requests to fill the field

my model

class Reservation(models.Model):
    user = models.ForeignKey(
        User, verbose_name='owner',
        on_delete=models.CASCADE,
        default=User.objects.all()[0].pk
    )
    RESERVATION_TYPES = (
        ('office', 'office'),
        ('workplace', 'workplace')
    )
    reservation_type = models.CharField(
        verbose_name='reservation type',
        choices=RESERVATION_TYPES,
        max_length=9,
        default='workplace'
    )
    office = models.ForeignKey(
        Office, verbose_name='offices for reservation',
        on_delete=models.CASCADE,
        default=Office.objects.all()[0].pk
    )
    workplaces = models.CharField(
        verbose_name='workplaces for reservation',
        blank=True,
        max_length=9
    )
    initial_day = models.DateField(
        verbose_name='days delta initial day',
        default=datetime.now() + timedelta(days=1)
    )
    days_delta = models.DurationField(
        verbose_name='days delta',
        null=True,
        default=timedelta(days=0)
    )

my serializer

class ReservationDetailSerializer(serializers.ModelSerializer):
    reservation_days = serializers.SerializerMethodField('get_reservation_days_list')

    class Meta:
        model = Reservation
        fields = (
            'id', 'reservation_type', 'office', 'workplaces',
            'initial_day', 'days_delta', 'reservation_days', 'user'
        )

    def get_reservation_days_list(self, reservation_model):
        initial_day = reservation_model.initial_day
        days_delta = reservation_model.days_delta
        reservation_days = []

        for delta in range(days_delta.days):
            reservation_days.append(date.isoformat(initial_day + timedelta(days=delta)))

        return reservation_days

    def validate(self, validated_data):
        validated_data['days_delta'] = validated_data['days_delta'] * 86400
        
        if validated_data['reservation_type'] == 'office':
            workplaces = []
            for workplace in Workplace.objects.all().filter(office=validated_data['office']):
                workplaces.append(workplace.pk)
            validated_data['workplaces'] = workplaces

        return validated_data

my view

class ReservationCreateView(generics.CreateAPIView):
    serializer_class = ReservationDetailSerializer
    permission_classes = (IsAuthenticated,)

request

days_delta in seconds then multiply by 86400 (seconds in a day) to write the correct interval to the database

days_delta in seconds then multiply by 86400 (seconds in a day) to write the correct interval to the database

{
    "reservation_type": "office",
    "office": 1,
    "initial_day": "2020-12-31",
    "days_delta": 5,
    "user": 2
}

response

days_delta need to become equal to 5 (days only)

{
    "id": 62,
    "reservation_type": "office",
    "office": 1,
    "workplaces": "[1, 2, 3, 4, 5]",
    "initial_day": "2020-12-31",
    "days_delta": "5 00:00:00",
    "reservation_days": [
        "2020-12-31",
        "2021-01-01",
        "2021-01-02",
        "2021-01-03",
        "2021-01-04"
    ],
    "user": 2
}

Help me, wested two days..


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

you can override the to_representation(self, value) method. This method takes the target of the field as the value argument, and should return the representation that should be used to serialize the target. The value argument will typically be a model instance.

To get days from timedelta use .days property.

serializer.py

class ReservationDetailSerializer(serializers.ModelSerializer):
    reservation_days = serializers.SerializerMethodField('get_reservation_days_list')

    class Meta:
        model = Reservation
        fields = (
            'id', 'reservation_type', 'office', 'workplaces',
            'initial_day', 'days_delta', 'reservation_days', 'user'
        )

    def to_representation(self, instance):
        change_fields = ( 'days_delta', )
        data = super().to_representation(instance)

        for field in change_fields:
            try:
                data[field] = field.days
            except Exception as e:
                print(e)
        return data 
                
    def get_reservation_days_list(self, reservation_model):
        initial_day = reservation_model.initial_day
        days_delta = reservation_model.days_delta
        reservation_days = []

        for delta in range(days_delta.days):
            reservation_days.append(date.isoformat(initial_day + timedelta(days=delta)))

        return reservation_days


    def validate(self, validated_data):
        validated_data['days_delta'] = validated_data['days_delta'] * 86400

        if validated_data['reservation_type'] == 'office':
            workplaces = []
            for workplace in Workplace.objects.all().filter(office=validated_data['office']):
                workplaces.append(workplace.pk)
            validated_data['workplaces'] = workplaces

        return validated_data

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...