如何在Django rest mixins中使用嵌套序列化器



我试图在Django-REST框架中实现多个模型的CRUD操作。目标是在调用API时对多个表执行CRUD操作。

我使用mixins从REST框架https://www.django-rest-framework.org/api-guide/generic-views/#mixins

我已经找到了一些相关的例子,但是,我的序列化器只返回CRUD操作的Student模型的字段。我无法在REst api ui中看到Course模型字段。

我无法从HomeworkCourse模型中获取字段。

如何显示数据从两个模型不创建新的模型在Django?

使用Django rest框架中定义的mixins类

models.py

class Student(models.Model):
student_id = models.UUIDField(default=uuid.uuid4, unique=True,
primary_key=True, editable=False)
firstName = models.CharField(max_length=20)
age = models.IntegerField(default=18)

class Course(models.Model):
student_id = models.ForeignKey(Student, on_delete=models.CASCADE)
courseName = models.CharField(max_length=20)
courseYear = models.IntegerField(default=2021)
student = models.ManyToManyField(Student, related_name='courses')

class Homework(models.Model):
student_id = models.ForeignKey(Student, on_delete=models.CASCADE)
hwName = models.CharField(max_length=20)
hwPossScore = models.IntegerField(default=100)
course = models.ForeignKey(Course, related_name='homeworks', on_delete=models.CASCADE, null=True, blank=True)
students = models.ManyToManyField(Student)

Serializers.py

class StudentSerializer(serializers.ModelSerializer):

class Meta:
model = Student
fields = "__all__"

class HomeworkSerializer(serializers.ModelSerializer):

class Meta:
model = Homework
fields = __all__

class CourseSerializer(serializers.ModelSerializer):

class Meta:
model = Course
fields = "__all__"
###I combine both Student and Course into one
class All_Serializer(serializers.ModelSerializer):

students = serializers.SerializerMethodField()
homeworks = serializers.SerializerMethodField()
courses = serializers.SerializerMethodField()

def get_students(self, obj):
students = obj.student_set.all()
serializer = StudentSerializer(students, many=True)
return serializer.data
def get_homeworks(self, obj):
homeworks = obj.homework_set.all()
serializer = HomeworkSerializer(homeworks, many=True, read_only=True)  
return serializer.data
def get_courses(self, obj):
courses = obj.courses_set.all()
serializer = CourseSerializer(courses, many=True, read_only=True)  
return serializer.data
class Meta:
model = Student
fields = ('student_id','firstName','age','homeworks','courses')

views.py

class Main_mixins(generics.GenericAPIView, 
mixins.ListModelMixin, 
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin):
serializer_class = All_Serializer
queryset = Student.objects.all()
lookup_field = 'student_id'
def get(self, request, student_id=None):
if student_id:
return self.retrieve(request, student_id)
else:
return self.list(request)

def post(self, request):
return self.create(request)

def perform_create(self, serializer):
serializer.save()


def put(self, request, student_id=None):
return self.update(request, student_id=None, homeworks, courses)

提前感谢您的帮助!

我不知道你想做什么。

coursehomework模型属于onestudent or to havemany的学生?如果我没有理解你实现的目的,请原谅。

但是如果你想让你的学生queryset包含一个课程和家庭作业字段。您可以尝试下面的代码。

models.py

class Student(models.Model):
student_id = models.UUIDField(default=uuid.uuid4, unique=True,
primary_key=True, editable=False)
firstName = models.CharField(max_length=20)
age = models.IntegerField(default=18)
def get_course_set(self):
return Course.objects.filter(student_id=self)
def get_homework_set(self):
return Homework.objects.filter(student_id=self)

class Course(models.Model):
...

class Homework(models.Model):
...

serializers.py

class HomeworkSerializer(serializers.ModelSerializer):

class Meta:
model = Homework
fields = __all__

class CourseSerializer(serializers.ModelSerializer):

class Meta:
model = Course
fields = "__all__"

class StudentSerializer(serializers.ModelSerializer):
course = CourseSerializer(source="get_course_set", many=True, read_only=True)
homework = HomeworkSerializer(source="get_homework_set", many=True, read_only=True)

class Meta:
model = Student
fields = "__all__"
# Remove All_Serializer
# class All_Serializer(serializers.ModelSerializer):
...

views.py


class Main_mixins(generics.GenericAPIView, 
mixins.ListModelMixin, 
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin):
# Change from All_Serializer to StudentSerializer
serializer_class = StudentSerializer
queryset = Student.objects.all()
lookup_field = 'student_id'
...

最新更新