ManyToManyField
Django에서 ManyToManyField란 다대다(N:M) 관계를 나타내는 필드이다. 이 필드를 사용하여 두 개의 모델 사이에 여러 개의 관계를 설정할 수 있습니다. ManyToManyField는 관계의 중간 테이블은 두 모델의 기본키(primary key)를 참조한다.
class Author(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField('Book')
class Book(models.Model):
title = models.CharField(max_length=200)
authors = models.ManyToManyField(Author)
예시 테이블을 하나 가져오면 Book과 Author 모델은 다대다 관계가 될 수 있다. 한 책은 여러 작가에 의해 쓰일 수 있고, 작가 역시 여러 책을 쓸 수 있다. 이 두 테이블을 연결하기 위해 모델에 각각 ManyToManyField를 추가하고 서로의 모델을 참조시킨다.
Django는 중간 테이블을 기본적으로 생성해주지만 직접 중간 테이블 모델을 추가하려면 ManyToManyField에 through 매개변수를 추가해 특정 중간 테이블을 참조할 수 있다. 중간 테이블 모델을 만들어 추가적인 데이터도 저장 가능하다.
class Author(models.Model):
name = models.CharField(max_length=100)
books = models.ManyToManyField('Book', through='BookAuthor')
class BookAuthor(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
extra_field = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=200)
authors = models.ManyToManyField(Author)
ManyToMany 인스턴스 생성
1. add()
ManyToManyField에서 제공하는 add() 메서드를 사용해 중간 테이블에 새로운 레코드를 추가하여 두 모델 사이의 관계를 설정할 수 있다.
author1 = Author.objects.get(name='z0')
book1 = Book.objects.get(title='Coding')
# 중간 테이블에 새로운 레코드 추가
book1.authors.add(author1)
2. 인스턴스 CREATE
add는 단순히 관계를 설정하는데 사용되는 메소드이다. 예시 모델처럼 extra_field 값도 같이 넣어서 생성하고 싶다면 add 메서드를 쓸 수 없다. 이 때는 일반 인스턴스 생성처럼 create 해야한다.
bookauthor_instance = BookAuthor.objects.create(book=book, author=author, extra_field='extra data')
ManyToMany 인스턴스 삭제
clear 메서드를 사용하면, 관계 테이블에서 특정 객체와의 모든 관계를 삭제할 수 있다.
book1.authors.clear()
Book 모델의 authors 필드를 사용하여 book1 인스턴스와 관계가 있는 모든 Author 인스턴스를 삭제한다. 즉, 중간 테이블에서 모든 관계를 삭제한다.
'Dev. > Django.' 카테고리의 다른 글
[DRF] Custom Permission 생성- BasePermission (0) | 2023.04.19 |
---|---|
[DRF] Serialization / Deserialization 동작 변경 - to_internal_value와 to_representation (0) | 2023.04.17 |
[Django] Django에서 fixture 사용 (0) | 2023.03.31 |
[Django] JSON WebToken - Simple JWT (0) | 2023.03.30 |
[Django] Django Middleware (0) | 2023.03.16 |