DRF reversed foreignkey get specific field

이지훈·2022년 5월 10일

DRF 에서 역참조 관계에 있는 테이블의 특정 필드를 가져오는 방법을 정리

우선 찾아본 방법은 3가지가 있었다.

  1. 간편하게 nested serializer 사용하기
  2. source 속성 사용해서 가져오기
  3. SerializerMethodField 사용하기

# models.py

class Task(models.Model):
    name = models.CharField(max_length=256)
    description = models.CharField(max_length=256)
    due_date = models.DateTimeField()
    is_complete = models.BooleanField(default=False)


class Air(models.Model):
    name = models.CharField(max_length=256)
    task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name="airs")
    
    
# views.py
class TaskView(APIView):

    def get(self, request):
        tasks = Task.objects.all()
        serializer = Taskserlizer(tasks, many=True, context={"request":"success"})
        return Response(data=serializer.data)

Task 테이블은 Air를 역참조하는 구조이다.


nested serializer 사용

class Airselializer(serializers.ModelSerializer):
    class Meta:
        model = Air
        fields = ('name',)



class Taskserlizer(serializers.ModelSerializer):
    airs = Airselializer(many=True)

    class Meta:
        model = Task
        fields = (
            'id',
            'name',
            'airs'
        )


2번째 source 사용하기

class TaskSerializer(serializers.ModelSerializer):
    airs_name = serializers.SlugRelatedField(
        source='airs',
        slug_field='name',
        many=True,
        read_only=True,
    )

    class Meta:
        model = Task
        fields = ('id', 'name', 'airs_name')

이번에는 slug 필드를 사용해서 값만 나오게 했다.
source는 참조할 테이블을 말한다(related_field name)
slug_field는 어떤 필드값을 가져올 것인지이다.


SerializerMethodField 사용하기

class Task1serlizer(serializers.ModelSerializer):
    airs_name = serializers.SerializerMethodField()

    def get_airs_name(self, obj):
        return obj.airs.all().values_list('name', flat=True)

    class Meta:
        model = Task
        fields = (
            'id',
            'name',
            'airs_name'
        )

SerializerMethodField는 없는 필드값을 만들기 위해 많이 쓰는것 같은데, 그렇다면 원하는 필드값만 반환하는데에도 사용될 수 있을 것이다.
오버라이드 하기 나름이니까...

이번에도 value만 리스트에 담았다. 키 값을 원하면 values_list를 다르게 바꾸면 될것 같다.


profile
꾸준하게 🐌

0개의 댓글