Django REST framework изменяет значения объектов, когда метод запроса - GET

У меня проблема с установкой значений (нежелательных) объектов. У меня есть набор представлений, где сериализатор выбирается по request.method. Я хочу обновлять DateTimeField только методом POST/PUT, а затем проверять это значение методом GET, но... после размещения нового объекта я получаю json следующего вида

{
    "datetimefield": "2021-10-26 23:01:53.272194"
}

а после метода GET я получил следующее (для того же объекта):

{
    "datetimefield": ""
}

мой код:

class SomeViewSet(viewsets.ModelViewSet):
    queryset = SomeModel.objects.all()

    def get_serializer_class(self):
        if (self.request.method == 'POST'):
            return FirstSerializer
        else:
            return SecondAppSerializer

class FirstSerializer(serializers.HyperlinkedModelSerializer):
    datetimefield = serializers.SerializerMethodField()

    def get_datetimefield(self, obj):
        return str(datetime.today())

    class Meta:
        model = SomeModel
        fields = ('datetimefield')

class SecondSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = SomeObject
        fields = ('datetimefield')

class SomeModel(models.Model):
    datetimefield  = models.CharField(max_length=100)

Кто-нибудь знает, как это решить?

Вы можете думать о SerializerMethodField как о вычисляемом поле только для чтения, поэтому вывод, который вы получили от POST, просто генерируется get_datetimefield и никогда не сохраняется в базе данных. Вот почему вы получаете пустые данные при GET.

Чтобы решить эту проблему, вы можете удалить поле datetimefield из сериализатора и позволить save обрабатывать его, переопределив perform_create:

class FirstSerializer(serializers.HyperlinkedModelSerializer):
    # remove datetimefield
    class Meta:
        model = SomeModel
        fields = ('some_other_fields...')


class SomeViewSet(viewsets.ModelViewSet):
    ...
    def perform_create(self, serializer):
        serializer.save(datetimefield=str(datetime.today()))

Или, если возможно, я настоятельно рекомендую просто изменить поле модели на DateTimeField с auto_now_add установленным на True.

При таком подходе нет необходимости управлять datetimefield на представлении или сериализаторе. Модель будет автоматически обрабатывать это за вас, когда создается новый объект. Итак:

class SomeModel(models.Model):
    datetimefield  = models.DateTimeField(auto_now_add=True)
Вернуться на верх