728x90

앞에서는 1:1 relationship, 1:N relationship을 살펴보았다면 이번엔 Many-to-many relationships M:N relationship에 대해서 알아보자.

한 테이블의 0개 이상의 레코드가 다른 테이블의 0개 이상의 레코드와 관련된 경우이며, 양쪽 모두에서 N:1 관계를 가진다.

 

목차

  1. Intro
  2. Django ManyToManyField
  3. 정리

1. Intro

 

※ 데이터 모델링

  • 주어진 개념으로부터 논리적인 데이터 모델을 구성하는 작업
  • 물리적인 데이터베이스 모델로 만들어 고객의 요구에 따라 특정 정보 시스템의 데이터베이스에 반영하는 작업

 

시작하기 전 용어 정리

 

  • target model
    • 관계 필드를 가지지 않은 모델
  • source model
    • 관계 필드를 가진 모델

 

N:1의 한계

 

  • 의사와 환자 간 예약 시스템을 구현해보자
  • 지금까지 배운 N:1 관계를 생각해 한 명의 의사에게 여러 환자가 예약할 수 있다고 모델 관계를 설정

 

  • 각각 2명의 의사와 환자를 생성하고 환자는 서로 다른 의사에게 예약을 했다고 가정

 

  • 1번 환자(carol)가 두 의사 모두에게 방문하려고 함

 

 

  • 여기서 동시에 예약을 할 수는 없을까?

 

  • 위에서 볼 수 있듯이 SyntaxError가 발생한다.
  • 동일한 환자지만 다른 의사에게 예약하기 위해서는 객체를 하나 더 만들어서 예약을 진행해야 함
  • 따라서 새로운 환자 객체를 생성할 수밖에 없음
  • 외래 키 컬럼에 '1,2' 형태로 참조하는 것은 Integer 타입이 아니기 때문에 불가능

 

그렇다면 "예약 테이블을 따로 만들자"

 

중개 모델

 

  • 환자 모델의 외래 키를 삭제하고 별도의 예약 모델을 새로 작성
  • 예약 모델은 의사와 환자에 각각 N:1 관계를 가짐

 

  • Model을 수정하고 나면 migration 진행하는 것 까먹지 말기!
  • 의사와 환자 생성 후 예약 만들기

 

  • 1번 의사에게 새로운 환자 예약이 생성된다면

 


2. Django ManyToManyField

 

  • 환자 모델에 Django ManyToManyField 작성

 

  • 마찬가지로 데이터베이스 초기화 후 Migration 진행

 

  • 의사 1명과 환자 2명 생성

 

  • 예약 생성 (환자가 의사에게 예약)

 

  • 예약 생성 (의사가 환자를 예약)

 

 

  • 예약 취소하기 (삭제)
  • 기존에는 해당하는 Reservation을 찾아서 지워야 했다면, 이제는 .remove() 사용

 

  • Django는 ManyToManyField를 통해 중개 테이블을 자동으로 생성한다.

 

 

'related_name' argument

 

  • target model이 source model을 참조할 때 사용할 manager name
  • ForeignKey()의 related_name과 동일

 

  • related_name 설정 값 확인하기

 

 

'through' argument

 

  • 그렇다면 중개 모델을 직접 작성하는 경우는 없을까?
    • 중개 테이블을 수동으로 지정하려는 경우 through 옵션을 사용하여 사용하려는 중개 테이블을 나타내는 Django 모델을 지정할 수 있음
  • 가장 일반적인 용도는 중개 테이블에 추가 데이터를 사용해 다대다 관계와 연결하려는 경우

 

  • through 설정Reservation Class 수정
    • 이제는 예약 정보에 증상과 예약일이라는 추가 데이터가 생김

 

  • 의사 1명과 환자 2명 생성

 

  • 예약 생성 1

 

  • 예약 생성 2
  •  ※ through_defaults 값에 딕셔너리 타입으로 입력

                                                

  • 예약 삭제

 

 


3. 정리

 

  • M:N 관계로 맺어진 두 테이블에는 변화가 없음
  • Django의 ManyToManyField는 중개 테이블을 자동으로 생성함
  • Django의 ManyToManyField는 M:N 관계를 맺는 두 모델 어디에 위치해도 상관없음
    • 대신 필드 작성 위치에 따가 참조와 역참조 방향을 주의할 것
  • N:1은 완전한 종속의 관계였지만 M:N은 의사에게 진찰받는 환자, 환자를 진찰하는 의사의 두 가지 형태로 모두 표현이 가능한 것
728x90