首页 > 解决方案 > 当请求方法为 GET 时,Django REST 框架正在更改对象值

问题描述

我对(不想要的)对象值设置有问题。我有由 request.method 选择序列化程序的视图集。我只想用 POST/PUT 方法更新 DateTimeField,然后可以用 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)

有谁知道如何解决这个问题?

标签: djangodjango-modelsdjango-rest-frameworkdjango-serializer

解决方案


您可以将其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()))

或者如果可能的话,我强烈建议将模型字段更改为DateTimeFieldwith auto_now_addset to True

在这种方法中,不需要对datetimefield视图或序列化程序进行管理。创建新对象时,模型会自动为您处理它。所以:

class SomeModel(models.Model):
    datetimefield  = models.DateTimeField(auto_now_add=True)

推荐阅读