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)