DRF reversed foreignkey get specific field

이지훈·2022년 5월 10일
0

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개의 댓글