我尝试使用ListSerializer
来过滤嵌套的序列化程序。除了创建新实例时的一种情况之外,这种方法完全可以正常工作。
view.py
如下所示:
class NewGrade(generics.RetrieveUpdateDestroyAPIView):
queryset = Grade.objects.all()
serializer_class = NewGradeSerializer
lookup_field = 'grade'
def put(self, request, *args, **kwargs):
try:
flag = 1
s1 = kwargs["schoolName"]
g1 = kwargs["grade"]
Grade = Grade.objects.get(school__schoolName=s1, grade=g1)
context = {'schoolName': kwargs["schoolName"]}
serializer = NewGradeSerializer(Grade, context = context, data=request.data)
except Grade.DoesNotExist:
flag = 0
context = {'schoolName': kwargs["schoolName"]}
serializer = NewGradeSerializer(context = context, data=request.data)
if serializer.is_valid():
if flag == 0:
serializer.create(validated_data=request.data)
else:
serializer.update(Grade,validated_data=request.data)
else:
return Response(serializer.errors)
return Response(serializer.data, status=status.HTTP_200_OK)
嵌套的序列化程序和ListSerilazer如下所示:
class FilteredData(serializers.ListSerializer):
def to_representation(self, data):
school = self.context.get("schoolName")
data = data.filter(schoolID__schoolName=school)
return super(FilteredData, self).to_representation(data)
class StudentTemp(serializers.ModelSerializer):
studentInfo = DisplayData(source="*")
class Meta:
model = Student
list_serializer_class = FilteredData
fields = ('studentInfo',)
class DisplayData(serializers.Serializer):
name = serializers.CharField()
rollNum = serializers.CharField()
class NewGradeSerializer(serializers.ModelSerializer):
studentList = StudentTemp(many=True)
class Meta:
model = Grade
fields = ("grade", "studentList")
def create(self, validated_data):
s1 = self.context.get("schoolName")
sch = School.objects.get(schoolName=s1)
student_datas = validated_data.pop('studentList')
grade = Grade.objects.create(**validated_data)
grade.school.set([sch]) #m2m field
for student_data in student_datas:
n1 = student_data["studentInfo"]["name"]
r1 = student_data["studentInfo"]["rollNum"]
student.objects.create(grade=grade, name=n1, rollNum=r1, schoolID = sch)
return grade
def update(self, instance, validated_data):
students_data = validated_data.pop('studentList')
for student_data in students_data:
student_up = Student.objects.get(rollNum = student_data["student"]["rollNum"])
student_up.name = student_data["studentInfo"]["name"]
student_up.save()
return instance
我在序列化器的许多地方都使用FilteredData
,并且在每种情况下都可以正常工作。但是当我尝试实现serializer.create(validated_data=request.data)
时,它给了我以下错误:
'list' object has no attribute 'filter'
JSON有效负载为:
{
"grade": "ten",
"studentList": [
{
"studentInfo": {
"name": "mark",
"rollNum": 4
}
}
]
}
此有效负载在更新时工作得很好,但在创建时却没有。我知道为什么会收到此错误,但是我不确定如何解决该错误。它也适用于'GET'
操作。也创建了新实例,但无法显示,而是显示错误。
编辑
我将data
打印在FilteredData
中,并将所有数据打印在studentList
中,而create
则不应该发生。而且在任何其他情况下都不会发生,无论为什么。