본문 바로가기

개발/Django

[Django] Nested Serializer (3): 다대다필드(ManyToManyField)를 Serializer로 내려주기

다대다 관계(ManyToMany)의 Model 을 내려주는 방법

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 모델을 가지는 Bookstore 라는 모델을 아래와 같이 작성했다.

 

class Bookstore(models.Model):
   class Meta:
      verbose_name = '서점'
      verbose_name_plural = verbose_name

   name = models.CharField(
      verbose_name='상호명',
      max_length=32,
   )
   address = models.CharField(
      verbose_name='주소',
      max_length=64,
   )
   contact = models.CharField(
      verbose_name='연락처',
      max_length=16,
   )
   books = models.ManyToManyField(
      to='Book',
      verbose_name='서적',
      blank=True,
      related_name='bookstores',
   )

서점은 여러개의 Book을 가질 수 있고, 각 Book 마다 여러개의 서점에 납품할 수 있기 때문에 ManyToManyField를 사용해야한다.

ManyToManyField를 nested serializer로 내려주려면 중첩시킬 serializer 끝 괄호 안에 아래 코드처럼 many=True라는 옵션을 넣어주어야한다.

 

class BookstoreSerializer(serializers.ModelSerializer):
    books = BookSerializer(many=True, allow_null=True)
    
    class Meta:
        model = Bookstore
        fields = (
            'id',
            'name',
            'address',
            'contact',
            'books',
        )

만약 BookstoreSerializer로 View(또는 ViewSet)로 만들어 GET 메소드로 호출할 때, Book 데이터베이스에 데이터가 있어야만 호출이 정상적으로 작동될 것이다. 하지만, 이걸 원하지않고 Book 데이터가 없어도 Bookstore 데이터들을 가져오려면 allow_null=True 옵션 또한 넣어주어야한다.