Django의 다대다 관계 설명

Django는 모델 간에 ManyToMany을 정의하기 위해 many-to-many relationships 필드를 제공합니다. 예를 들어 Books와 Authors라는 두 모델 간에 다대다 관계를 정의해야 하는 경우 다음과 같이 할 수 있습니다.

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name


class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)

    def __str__(self):
        return self.title


이 관계는 저자가 한 권 이상의 책을 쓸 수 있는 반면 책은 한 명 이상의 저자가 쓸 수 있음을 알려줍니다.
이제 Django에서 다대다 관계가 작동하는 방식을 이해하기 위해 일부 데이터로 모델을 채워 보겠습니다.

저자 J.K Rowling과 그녀가 저술한 소설 3권을 데이터베이스에 추가해 보겠습니다. 관계형 데이터베이스 SQLite를 사용하겠습니다.

>>> a1 = Author(name="J.K. Rowling")
>>> a1.save()

>>> b1 = Book(title="Harry Potter and the Philosopher's Stone")
>>> b2 = Book(title="Harry Potter and the Chamber of Secrets")
>>> b3 = Book(title="Harry Potter and the Goblet of Fire")
>>> b1.save()
>>> b2.save()
>>> b3.save()

>>> b1.authors.add(a1)
>>> b2.authors.add(a1)
>>> b3.authors.add(a1)


"The Talisman"과 "Black House"라는 제목의 소설은 Stephen King과 Peter Straub가 썼습니다. 이 데이터도 추가해 보겠습니다.

>>> a2 = Author(name="Stephen King")
>>> a3 = Author(name="Peter Straub")
>>> a2.save()
>>> a3.save()

>>> b4 = Book(title = "The Talisman")
>>> b4.save()
>>> b4.authors.add(a2)
>>> b4.authors.add(a3)

>>> b5 = Book(title = "Black House")
>>> b5.save()
>>> b5.authors.add(a2)
>>> b5.authors.add(a3)


"The Talisman"이라는 책의 저자를 가져오고 싶다고 가정해 보겠습니다. 다음과 같이 할 수 있습니다.

>>> book = Book.objects.get(title="The Talisman")
>>> book.title
'The Talisman'
>>> book.authors.all()
<QuerySet [<Author: Stephen King>, <Author: Peter Straub>]>


이제 J.K.가 저술한 모든 책을 검색하고 싶습니다. 롤링. 다음과 같이 할 수 있습니다.

>>> author = Author.objects.get(name = "J.K. Rowling")
>>> author.name
'J.K. Rowling'
>>> author.book_set.all()
<QuerySet [<Book: Harry Potter and the Philosopher's Stone>, <Book: Harry Potter and the Chamber of Secrets>, <Book: Harry Potter and the Goblet of Fire>]>


이제 이러한 관계가 실제로 어떻게 정의되는지 알아보기 위해 데이터베이스를 살펴보겠습니다. 데이터베이스 검색을 위해 SQLite용 DB 브라우저를 사용하겠습니다.

저자의 테이블은 다음과 같습니다.



그리고 책의 테이블은 아래와 같습니다.



Books 모델에서 "authors"라는 이름의 ManyToManyField를 정의했으며 해당 필드를 사용하여 특정 책의 저자를 검색하고 있습니다. 그러나 해당 필드는 books 테이블에서 볼 수 없습니다. 왜 이렇게이다?

이는 Django가 책과 저자 간의 관계를 정의하기 위해 데이터베이스에 또 다른 테이블을 생성했기 때문입니다. 표는 다음과 같습니다.



이 테이블은 책과 저자 간의 관계를 저장합니다. author_id 1은 J.K. Rowling과 book_ids 1,2 및 3은 그녀가 쓴 세 권의 책에 해당합니다. 비슷하게,
author_ids 2와 3은 각각 Stephen King과 Peter Straub에 해당하고 book_ids 4와 5는 소설 "The Talisman"과 "Black House"에 각각 해당합니다.

순수 SQL 쿼리를 사용하여 이러한 관계를 정의하는 것은 더 어려운 작업이었지만 Django ORM을 사용하면 개발자가 이러한 관계를 쉽게 정의하는 동시에 데이터베이스가 normalized인지 확인할 수 있습니다.

좋은 웹페이지 즐겨찾기