簡體   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