如何在 DRF 中使字段可编辑=False



我有一个序列化程序。我想限制更新字段。我该怎么做?

class ABCSerializer(serializers.ModelSerializer):
class Meta:
"""Meta."""
model = ModelA
fields = ('colA', 'colB', 'colC',)

colA是创建对象时的必填字段。但是,不应允许它更新。我该怎么做??

你可以使用 Django REST 框架字段级验证,通过验证该字段在更新时没有更改,如下所示:

from rest_framework.exceptions import ValidationError
class ABCSerializer(serializers.ModelSerializer):
colA = serializers.CharField(max_length=100)
def validate_colA(self, value):
if self.instance and self.instance.colA != value:
raise ValidationError("You may not edit colA")
return value
class Meta:
"""Meta."""
model = ModelA
fields = ('colA', 'colB', 'colC',)

这将检查这是否是更新(通过检查是否在序列化程序上填充了实例(,如果是,它将检查您是否对字段进行了更改,如果有,则会抛出ValidationError。此方法的好处是,您可以保持视图代码与以前相同,并继续在序列化程序中保留验证行为。

听起来您需要不同的序列化程序来PUTPOST方法。在PUT方法的序列化程序中,可以将colA字段设置为readonly

class ABCViewSet(ModelViewSet):
serializer_class = ABCSerializer
def get_serializer_class(self):
serializer_class = self.serializer_class
if self.request.method == 'PUT':
serializer_class = SerializerWithReadOnlyColA
return serializer_class

我认为现在回答为时已晚,但这可能对其他人有用:(

您可以通过以下方式解决问题:

class ABCSerializer(serializers.ModelSerializer):
class Meta:
model = ModelA
fields = ('colA', 'colB', 'colC',)

def get_fields(self):
fields = super().get_fields()
if self.instance:
fields["colA"].read_only = True
return fields

当您要创建时,self.instance为 None,它将传递 if 子句,在更新 if 子句的情况下,将使该字段只读且不可编辑。

可以重写序列化程序的update方法,以仅更新所需的字段。

class ABCSerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
instance.colB = validated_data.get('colB', instance.colB)
instance.colC = validated_data.get('colC', instance.colC)
# do nothing to instance.colA
instance.save()
return instance
class Meta:
model = ModelA
fields = ('colA', 'colB', 'colC',)

或者,如果您有很多字段,并且只想省略更新colA,则可以像这样编写update方法:

def update(self, instance, validated_data):
validated_data.pop('colA') # validated_data no longer has colA
return super().update(instance, validated_data)

您可以在此处阅读有关覆盖update的更多信息:https://www.django-rest-framework.org/api-guide/serializers/#saving-instances

您可以使用read_only_fields选项执行此操作

class ABCSerializer(serializers.ModelSerializer):
class Meta:
"""Meta."""
model = ModelA
fields = ('colB', 'colC',)
read_only_fields = ('colA',)

最新更新