모델 시리얼라이저를 사용하면 모델 객체를 JSON으로 직렬화할 수 있다. 그런데, 시리얼라이저 객체를 생성할 때 many=True
옵션을 주어야 하는 경우가 있다.
직관적으로 생각하면 여러 모델 객체를 직렬화하기 위해 사용하는 옵션으로 보인다. 하지만 주의해야 할 점이 있다. 다음과 같은 코드를 생각해보자.
# views.py
...
article = Article.objects.get(pk=pk)
serializer = ArticleDetailSerializer(article)
return Response(serializer.data, status=status.HTTP_200_OK)
게시글 하나를 직렬화해서 응답하는 코드이다. 이렇게 작성하면 문제가 없다. 다음과 같이 변경해보자.
# views.py
...
article = Article.objects.filter(pk=pk)
serializer = ArticleDetailSerializer(article)
return Response(serializer.data, status=status.HTTP_200_OK)
이제 다시 상세 페이지 요청을 하면 아래의 에러가 발생한다.
AttributeError: Got AttributeError when attempting to get a value for field
title
on serializerArticleDetailSerializer
.
The serializer field might be named incorrectly and not match any attribute or key on theQuerySet
instance.
Original exception text was: 'QuerySet' object has no attribute 'title'.
시리얼라이저는 모델 객체가 들어오길 기대했지만, 쿼리셋을 넣어 주었기 때문에 객체의 속성을 참조하지 못했다는 의미이다. 실제로 get
은 단 하나의 모델 객체를 반환하지만 filter
는 항상 쿼리셋을 반환하기 때문에 두 번째 코드에서 시리얼라이저에 전달한 article
은 쿼리셋이다. 즉, 하나의 게시글이 담겨 있지만 쿼리셋이기 때문에 오류가 발생한 것이다.
이것을 해결하기 위해서는 get
을 사용하거나 시리얼라이저에 쿼리셋을 인자로 전달할 경우 many=True
옵션을 주면 된다. 즉, 이 옵션은 다수의 모델 객체를 전달하거나 쿼리셋을 전달하는 경우에는 반드시 넣어야 한다.