You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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后台显示,有两种可选方案:

  1. 去掉模型的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)
    
  2. 在序列化器中显式覆盖字段,强制设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:35:23