我有一个序列化程序。我想限制更新字段。我该怎么做?
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
。此方法的好处是,您可以保持视图代码与以前相同,并继续在序列化程序中保留验证行为。
听起来您需要不同的序列化程序来PUT
和POST
方法。在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',)