繁体   English   中英

如何从 Django Rest-API 中的不同模型获取数据

[英]How to get data from different models in Django Rest-API

我有三个模型,学生,课程和家庭作业:

发生的事情是我有一个前端,用户可以在 ie 中输入这些字段。 来自StudentCourseHomework的所有字段,一旦这些字段被填写,他们应该点击submit以执行CREATE操作。 这会触发views.py中的CreatedData函数。

我找到了一些相关的例子,但我的序列化程序只返回Student模型中的字段以进行CRUD操作。 我无法获得CourseHomework模型字段。

在 Django REST Framework 的 CreateAPIView 中的 create() 之后返回不同的序列化程序

Django 休息 API。 在单个 API 调用中获取来自不同模型的所有数据

如何通过 DJANGO REST API 从模型中检索和创建数据?

如何通过 django rest api 中的一个序列化程序发布多个模型数据

模型.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)

对于这三个模型,我有三个序列化器类,并结合一个来获取一个 API 调用的所有数据: 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 Combined_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')
   

视图.py

 class CreatedData(viewsets.ModelViewSet):

     queryset = Student.objects.all()

     serializer_class = Combined_Serializer


    def create(self, request, pk=None):
       serializer = self.get_serializer(data=request.data) 
       serializer.is_valid(raise_exception=True)
       self.perform_create(serializer)
       headers = self.get_success_headers(serializer.data)
       student_id  = serializer.data['student_id']
       name = serializer.data['Name']        
       student_age = serializer.data['age'] 
       print("SERIALIZER.DATA >" , serializer.data)
       print("HEADERS", headers)

当我打印serializer.data时,我无法看到Course & Homework模型字段,只有来自Student模型的字段我才能获得这些字段。

我想设计一个视图,我可以访问所有表中的所有字段。 我想在用户单击submit按钮后获取它们。

如何设计视图以获取 Django rest API 中的其他信息?

提前感谢您的帮助!

Combined_Serializer仅返回学生字段,因为:

  • 模型设置:在Meta中, model = Student
  • 关系: students = obj.student_set.all() <- 你能解释一下这种关系是如何工作的吗?

如果您必须在序列化程序中指定模型,您可以创建一个与所有三个模型(学生、课程、作业)具有外键关系的抽象模型,并相应地修改您的序列化程序。 但仅在该类具有可靠用途和单一职责时才建议使用。

class StudentCourseHomework: 
    
```you can name it better with abstract term that explains 
what you want to do with this model```

    student = models.ForeignKey()
    course = models.ForeignKey()
    homework = models.ForeignKey()

    class Meta:
        abstract = True

备择方案

您可以使用serializers.Serializer创建没有模型的序列化程序。

class CombinedSerializer(serializers.Serializer):
    class Meta:
        fields = StudentSerializer.Meta.fields
        + CoursetSerializer.Meta.fields
        + HomeworkSerializer.Meta.fields

其他事情

  • 删除类名中的下划线会更干净。
  • 如果您真的打算制作具有所有三个模型字段的序列化程序,那么使用更具体的名称可能会更好。
  • 或者您可以使用视图类名称,如CreateDataSerializer
class CombinedCreateSerializer(serializers.Serializer):
    students = NewStudentSerializer()
    homeworks = NewHomeworkSerializer() # with minimal fields required to create like student_id is not required as it will be obtained later
    courses = NewCourseSerializer() # with minimal fields

    def create(self, validated_data):
        student = Student.objects.create(**validated_data['students'])
        # add student id in courses data
        courses = Course.objects.create(**validated_data['courses'])
        # add student id and course id in homeworks data
        homeworks = Homework.objects.create(**validated_data['homework'])
        return student

在视图中

class CreatedData(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = Combined_Serializer # your previously defined

    def create(self, request):
       # first verify combined create serializer
       combined_create_serializer = CombinedCreateSerializer(data=request.data) 
       combined_create_serializer.is_valid(raise_exception=True)
       student_instance = self.perform_create(combined_create_serializer)
       combined_serializer_data = self.get_serializer(student_instance) # your final data here which is from previously defined
       # ... rest of your codes

在过去,我已经实现了类似的操作; 祝你好运

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM