[python] Django Rest Framework를 사용하여 관련 모델 필드를 어떻게 포함합니까?

다음과 같은 모델이 있다고 가정 해 봅시다.

class Classroom(models.Model):
    room_number = [....]

class Teacher(models.Model):
    name = [...]
    tenure = [...]
    classroom = models.ForeignKey(Classroom)

ManyRelatedPrimaryKeyField 함수에 따라 다음과 같은 결과를 얻는 대신에

{
    "room_number": "42",
    "teachers": [
        27,
        24,
        7
    ]
},

다음과 같은 전체 관련 모델 표현을 포함하는 것을 반환하십시오.

{
    "room_number": "42",
    "teachers": [
        {
           'id':'27,
           'name':'John',
           'tenure':True
        },
        {
           'id':'24,
           'name':'Sally',
           'tenure':False
        },
    ]
},

이게 가능해? 그렇다면 어떻게? 그리고 이것은 나쁜 생각입니까?



답변

가장 간단한 방법은 깊이 인수 를 사용 하는 것입니다

class ClassroomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Classroom
        depth = 1

그러나 이는 선임 관계에 대한 관계 만 포함하며,이 경우 교사 필드는 역 관계이기 때문에 필요한 것은 아닙니다.

더 복잡한 요구 사항이있는 경우 (예 : 역 관계 포함, 일부 필드 중첩, 다른 필드 제외) 또는 특정 필드 하위 집합 만 중첩하는 경우 serializer중첩 시킬 수 있습니다 .

class TeacherSerializer(serializers.ModelSerializer):
    class Meta:
        model = Teacher
        fields = ('id', 'name', 'tenure')

class ClassroomSerializer(serializers.ModelSerializer):
    teachers = TeacherSerializer(source='teacher_set')

    class Meta:
        model = Classroom

serializer 필드에서 source 인수를 사용하여 필드의 소스로 사용할 속성을 지정하십시오. source대신 모델 teachers에서 related_name 옵션을 사용하여 속성이 있는지 확인 하여 인수를 삭제할 수 있습니다 Teacher.classroom = models.ForeignKey(Classroom, related_name='teachers')

명심해야 할 것은 중첩 된 직렬 변환기가 현재 쓰기 작업을 지원하지 않는다는 것입니다. 쓰기 가능한 표현의 경우 pk 또는 하이퍼 링크와 같은 일반적인 평면 표현을 사용해야합니다.


답변

감사합니다 @TomChristie !!! 당신은 저를 많이 도와주었습니다! 실수를했기 때문에 조금 업데이트하고 싶습니다.

class TeacherSerializer(serializers.ModelSerializer):
    class Meta:
        model = Teacher
        fields = ('id', 'name', 'tenure')

class ClassroomSerializer(serializers.ModelSerializer):
    teachers = TeacherSerializer(source='teacher_set', many=True)

    class Meta:
        model = Classroom
        field = ("teachers",)


답변

이것은 drf-flex-fields 라고 불리는 매우 편리한 dandy django 패키지를 사용하여 수행 할 수도 있습니다 . 우리는 그것을 사용하고 꽤 굉장합니다. 그냥 설치하고 pip install drf-flex-fields시리얼 라이저를 통해 전달하고 추가 expandable_fields하고 빙고하십시오 (아래 예). 도트 표기법을 사용하여 깊은 중첩 관계를 지정할 수도 있습니다.

from rest_flex_fields import FlexFieldsModelSerializer

class ClassroomSerializer(FlexFieldsModelSerializer):
    class Meta:
        model = Model
        fields = ("teacher_set",)
        expandable_fields = {"teacher_set": (TeacherSerializer, {"source": "teacher_set"})}

그런 다음 ?expand=teacher_setURL에 추가 하면 확장 된 응답이 반환됩니다. 언젠가 누군가에게 도움이되기를 바랍니다. 건배!


답변