Django DRF序列化器data/validated_data为空问题及成因疑问
这是预期行为,并非Bug
Django模型里的editable=False字段,会被DRF的ModelSerializer默认视为只读字段,哪怕你在序列化器的extra_kwargs里手动设置required=True也会被覆盖。
具体原因:
editable=False原本是用来告诉Django:这个字段不需要在Admin后台或ModelForm中展示编辑。DRF的ModelSerializer会继承这个语义,自动把这类字段标记为read_only=True。- 只读字段在反序列化过程中会被完全忽略——所以你传入的
latitude和longitude数据根本不会进入验证流程,自然不会出现在validated_data里,调用save()时就触发了数据库的非空约束错误。
验证方式:
在你的测试代码里加一行打印,就能确认这一点:
serializer = LocationSerializer(data=location_serializer_data) print(serializer.fields['latitude'].read_only) # 输出True
解决方案:
如果你需要这些字段能接受反序列化输入,但又不想在Admin后台显示,有两种可选方案:
- 去掉模型的
editable=False,然后在Admin类里排除这些字段:# admin.py from django.contrib import admin from .models import Location class LocationAdmin(admin.ModelAdmin): exclude = ('latitude', 'longitude') admin.site.register(Location, LocationAdmin) - 在序列化器中显式覆盖字段,强制设置
read_only=False:class LocationSerializer(serializers.ModelSerializer): latitude = serializers.FloatField( required=True, validators=[MaxValueValidator(90), MinValueValidator(-90)], read_only=False ) longitude = serializers.FloatField( required=True, validators=[MaxValueValidator(180), MinValueValidator(-180)], read_only=False ) class Meta: model = Location fields = ('address', 'latitude', 'longitude')
内容的提问来源于stack exchange,提问作者jolim
相关产品推荐
相关产品推荐

