Как показывать и использовать только дни в datetime в полях модели DRF и отправлять запросы на заполнение поля

#python #django #datetime #django-rest-framework

#python #django #datetime #django-rest-framework

Вопрос:

моя модель

 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)
    )
 

мой сериализатор

 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
 

мое мнение

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

запрос

days_delta в секундах затем умножьте на 86400 (секунды в день), чтобы записать правильный интервал в базу данных

days_delta в секундах затем умножьте на 86400 (секунды в день), чтобы записать правильный интервал в базу данных

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

ответ

days_delta должен стать равным 5 (только дни)

 {
    "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
}
 

Помогите мне, мы потратили два дня..

Комментарии:

1. « def to_representation(self, reservation_model): change_fields = (‘days_delta’, ) data = super().to_representation(reservation_model) для поля в change_fields: попробуйте: data[field] = int(data[field].split(‘ ‘)[0]) за исключением исключения как e: print(e) возвращает данные « В этой форме теперь его работа. Большое вам спасибо! @Sohaib

Ответ №1:

вы можете переопределить to_representation(self, value) метод. Этот метод принимает цель поля в качестве аргумента значения и должен возвращать представление, которое следует использовать для сериализации цели. Аргумент value обычно будет экземпляром модели.

Чтобы получить дни из timedelta .days свойства use.

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
 

Комментарии:

1. список значений по умолчанию только в ответ ( @Sohaib

2. извините, я забыл добавить оператор return .

3. « def to_representation(self, reservation_model): change_fields = (‘days_delta’, ) data = super().to_representation(reservation_model) для поля в change_fields: попробуйте: data[field] = int(data[field].split(‘ ‘)[0]) за исключением исключения как e: print(e) возвращает данные « В этой форме теперь его работа. Большое вам спасибо!