如何在Postman中通过嵌套Serializer关联已有Student添加Marks数据?
解决Django REST Framework嵌套Serializer关联已有Student而非创建新对象的问题
问题原因
当前MarksSerializer中直接使用StudentSerializer作为student字段,DRF默认会将嵌套的Student数据视为新对象进行创建,导致每次提交Marks时都会生成新的Student记录。
解决方案
方案1:通过主键ID关联已有Student(推荐)
这种方式最直接,写入时仅传递Student的ID,序列化输出时仍可显示Student的完整信息:
修改Serializers.py:
from rest_framework import serializers from .models import Student, Marks class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student fields = '__all__' class MarksSerializer(serializers.ModelSerializer): # 仅用于序列化输出,展示Student的详细信息 student_details = StudentSerializer(source='student', read_only=True) # 写入时接收Student的主键ID,限定为已存在的Student student = serializers.PrimaryKeyRelatedField(queryset=Student.objects.all()) class Meta: model = Marks # 包含student(用于写入)和student_details(用于输出) fields = ['id', 'student', 'student_details', 'maths', 'science', 'social']
方案2:通过Student的唯一字段关联(如mobile_no)
如果不想传递主键ID,希望通过Student的唯一标识(比如mobile_no)关联已有对象,可重写MarksSerializer的create方法:
修改Serializers.py:
from rest_framework import serializers from .models import Student, Marks from django.core.exceptions import ObjectDoesNotExist class StudentSerializer(serializers.ModelSerializer): class Meta: model = Student fields = '__all__' class MarksSerializer(serializers.ModelSerializer): student = StudentSerializer() class Meta: model = Marks fields = '__all__' def create(self, validated_data): # 提取嵌套的Student数据 student_data = validated_data.pop('student') try: # 通过唯一字段mobile_no获取已有Student student = Student.objects.get(mobile_no=student_data['mobile_no']) except ObjectDoesNotExist: # 若不存在,抛出验证错误 raise serializers.ValidationError("该Student不存在") # 创建Marks并关联找到的Student marks = Marks.objects.create(student=student, **validated_data) return marks
Postman发送数据示例
对应方案1(主键ID关联)
- 请求方法:
POST - 请求URL:
http://localhost:8000/[你的Marks路由路径]/ - 请求头:添加
Content-Type: application/json - 请求体(Raw JSON格式):
{ "student": 1, // 替换为已存在的Student的主键ID "maths": 88, "science": 92, "social": 75 }
对应方案2(唯一字段关联)
- 请求体(Raw JSON格式):
{ "student": { "mobile_no": "13800138000" // 替换为已存在Student的mobile_no }, "maths": 88, "science": 92, "social": 75 }
内容的提问来源于stack exchange,提问作者Rohit Gajula
相关产品推荐
相关产品推荐

