DRF创建Location对象报NOT NULL constraint failed: locations_location.city_id如何解决
问题原因
报错NOT NULL constraint failed: locations_location.city_id的核心原因是你提交的city外键ID没有被序列化器正常接收写入,导致创建Location对象时缺少关联的city字段值,触发数据库非空约束。
具体是你的LocationSerializer存在两个错误配置:
- 你设置了
depth = 1参数:DRF中使用depth参数配置嵌套序列化深度时,所有关联外键字段会被默认设置为只读属性,你POST提交的city: 1参数会被序列化器直接忽略,不会进入validated_data - 你在
create方法中定义city = serializers.PrimaryKeyRelatedField(...)的代码完全无效:序列化器字段必须定义在类的顶层作用域才能生效,写在create方法内的这段代码没有任何作用,也不会帮你处理传入的city参数。
修复方案
修改LocationSerializer的代码即可解决问题,调整如下:
class LocationSerializer(serializers.ModelSerializer): location_events = serializers.PrimaryKeyRelatedField(many=True, read_only=True) booked_days = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Location fields = "__all__"
如果你需要查询返回Location数据时嵌套展示关联City的完整信息,可以额外重写to_representation方法实现,不会影响写入逻辑:
class LocationSerializer(serializers.ModelSerializer): location_events = serializers.PrimaryKeyRelatedField(many=True, read_only=True) booked_days = serializers.PrimaryKeyRelatedField(many=True, read_only=True) class Meta: model = Location fields = "__all__" def to_representation(self, instance): rep = super().to_representation(instance) # 返回时嵌套展示city的完整信息,不影响写入逻辑 rep["city"] = CitySerializer(instance.city).data return rep
验证
修改后重新提交你现有的POST测试数据,即可正常创建关联了id为1的City的Location对象。
内容的提问来源于stack exchange,提问作者keystroke33
相关产品推荐
相关产品推荐

