我有一个带有外键的模型的序列化器.要求是在创建时,可以将外键设置为相关模型中的任何现有对象,但是在更新时,不能更改相关对象.我可以在自定义中检查这个update(),但是使用序列化验证来检查这个会更优雅吗?但我不确定如何.示例代码:
class Person(models.Model):
name = models.CharField(max_length=256)
spouse = models.ForeignKey(Person)
class PersonSerializer(serializers.ModelSerializer):
class Meta:
model = Person
# this is how I know how to do this
def create(self, validated_data):
try:
spouse = Person.objects.get(pk=int(validated_data.pop('spouse')))
except Person.DoesNotExist:
raise ValidationError('Imaginary spouses not allowed!')
return Person.objects.create(spouse=spouse, **validation_data)
def update(self, person, validated_data):
if person.spouse.pk != int(validated_data['spouse']):
raise ValidationError('Till death do us part!')
person.name = validation_data.get('name', person.name)
person.save()
return person
# the way I want to do this
def validate_spouse(self, value):
# do validation …Run Code Online (Sandbox Code Playgroud) 在DRF中使用可写嵌套序列化程序时,验证最终唯一字段并阻止更新父序列化程序存在已知问题.在这样的问题中已多次询问此问题:
为简单起见,我们以第一个问题为例:
class GenreSerializer(serializers.ModelSerializer):
class Meta:
fields = ('name',) #This field is unique
model = Genre
extra_kwargs = {
'name': {'validators': []},
}
class BookSerializer(serializers.ModelSerializer):
genre = GenreSerializer()
class Meta:
model = Book
fields = ('name', 'genre')
def create(self, validated_data):
# implement creating
def update(self, instance, validated_data):
# implement updating
Run Code Online (Sandbox Code Playgroud)
现在问题是,唯一性验证也被删除以用于创建.这可以在视图中截获,例如:
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer = BookSerializer
def perform_create(self):
# implement logic and raise ValidationError
Run Code Online (Sandbox Code Playgroud)
然而,这感觉不太对,因为我们正在验证Genrein 的唯一性BookViewSet.
另一种选择是在第二个问题中解释的 …