본문 바로가기

개발/Django

[Django] Nested Serializer (1): 정참조하고 있는 모델을 Serializer로 내려주기

정참조하는 Model 을 내려주는 방법

 

class BookAuthor(models.Model):
	class Meta:
		verbose_name = '작가'
		verbose_name_plural = verbose_name

	name = models.CharField(
		verbose_name='이름',
	)
	real_name = models.CharField(
		verbose_name='실명',
		null=True,
		blank=True,
	)
	introduction = models.TextField(
		verbose_name='소개',
		null=True,
		blank=True,
	)


class Book(models.Model):
	class Meta:
		verbose_name = '책'
		verbose_name_plural = verbose_name

	title = models.CharField(
		verbose_name='제목',
		max_length=32,
	)
	price = models.PositiveIntegerField(
		verbose_name='가격',
		default=0,
	)
	inventory_amount = models.PositiveIntegerField(
		verbose_name='재고 수량',
		default=0,
	)
	author = models.ForeignKey(
		to='BookAuthor',
		on_delete=models.SET_NULL,
		related_name='books',
	)
	published_at = models.DateField(
		verbose_name='발매일',
	)

위와 같이 Book이 BookAuthor 를 참조하는데, Book 을 Serializer로 내려주는 방법을 설명한다.

아래 코드처럼 작성하고 GET 메소드로 호출하면, 'author'는 serialize 할 수 없다며 에러가 날 것이다. 

💡 본 포스트에 계속 설명이 될 모델명은 대문자로 시작하며, 필드명은 소문자로 시작한다. (ex. Book 은 모델, books는 필드명)

 

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = (
            'id',
            'title',
            'price',
            'inventory_amount',
            'author',
            'published_at',
        )

 

왜냐하면 serializer를 이용해 데이터를 내려주려면, Author 모델 또한 먼저 serizlier로 정의하고, BookSerializer 안에서 위에서 정의한 AuthorSerializer를 가져와서 정의해주어야한다. serializer들을 중첩하기 때문에 이것을 Nested Serializer 라고 부른다.

 

Nested Serializer 를 활용한 예

class BookAuthorSerializer(serializers.ModelSerializer):  # Serizlier 정의
    class Meta:
        model = BookAuthor  # Model 이름
        fields = (
            'id',  # 내려주고 싶은 데이터들의 field 이름을 문자열 타입으로 적는다.
            'name',
            'real_name',
            'introduction',
        )
        
    
class BookSerializer(serializers.ModelSerializer):
    author = BookAuthorSerializer(required=False)  # Book Model 안의 ForeignKey의 이름으로 정의한다.
    
    class Meta:
        model = Book
        fields = (
            'id',
            'title',
            'price',
            'inventory_amount',
            'author',
            'published_at',
        )

 

주의할 점은, 중첩해서 내려주려고하는 외래키(ForeignKey)의 필드명 그대로 사용해야한다.