The Boxer

[Django] M : N Relation 구현 본문

Django

[Django] M : N Relation 구현

Prower 2019. 4. 12. 17:59
728x90
반응형

django를 사용해 M : N 관계를 구현하고, 간단한 조회, 삽입 기능을 구현해봅니다

 

I. M : N 관계

M쪽의 하나의 레코드가 N쪽의 다수의 레코드와 관계를 맺고,

N쪽의 하나의 레코드도 M쪽의 다수의 레코드와 관계를 맺는 관계

 

(1) 1 : N 관계와 비교

- 반드시 N쪽의 레코드가 1쪽의 레코드에 속함

- 1 has many N

- N belongs to 1

 

(2) 구현 방법

- 1 : N 관계를 사용하는 방법

  • 1 : N 테이블 2개를 구성
  • 2개 테이블의 pk를 데이터로 갖는 또 다른 테이블 구성
  • 결국 1 : N 2개를 사용하여 해결하는 방법

- django-ORM을 통해 해결하는 방법

  • django가 제공하는 기능을 사용하여 해결

 

(3) 1 : N 관계 사용

구현 예시

class Student(models.Model):
    name = models.CharField(max_length=30)
    student_id = models.IntegerField()


class Lecture(models.Model):
    lecture_title = models.CharField(max_length=100)
    

class Enrollment(models.Model):
    lecture = models.ForeignKey(Lecture, on_delete=models.CASCADE)
    student = models.ForeignKey(Student, on_delete=models.CASCADE)
  • Student, Lecture 테이블을 구성하고
  • Enrollment 테이블에서 둘의 pk를 받아 연결

- 그러나, Student와 Lecture를 직접 연결했다는 느낌이 들지 않는다

- 또한, Student가 듣고 있는 Lecture를 검색하는 경우에도 Enrollment를 거쳐가야 하는 번거로움이 있음

 

 

II. ManyToManyField()

테이블을 따로 생성하지 않고 direct한 M : N 관계를 만들고 싶다

실제로 연결하는 테이블은 django가 생성

두 테이블의 M : N 관계를 맺어주는 필드

ManyToManyField("연결할 모델 클래스 이름")
  • on_delete 필수 아님
  • 어떤 테이블에서 선언해도 상관 없음
  • python은 위에서 아래로 코드를 읽기 때문에 model을 선언하는 순서는 주요

 

사용 예시

class Client(models.Model):
    name = models.CharField(max_length=30)
    
    
class Resort(models.Model):
    name = models.CharField(max_length=30)
    clients = models.ManyToManyField(Client)
  • Resort 클래스에서 Client와 M : N 관계를 형성

 

makemigration 결과

--
-- Create model Client
--
CREATE TABLE "sugangs_client"...
--
-- Create model Resort
--
CREATE TABLE "sugangs_resort"...
--------------------------------------------------------------------------------------
CREATE TABLE "sugangs_resort_clients" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
"resort_id" integer NOT NULL REFERENCES 
"sugangs_resort" ("id") DEFERRABLE INITIALLY DEFERRED, 
"client_id" integer NOT NULL REFERENCES 
"sugangs_client" ("id") DEFERRABLE INITIALLY DEFERRED);
--------------------------------------------------------------------------------------
...
  • django가 sugangs_resort_clients라는 테이블을 생성
  • 이후 django를 통해 Client, Resort 테이블을 연결하여 사용

 

 

 

728x90
반응형

'Django' 카테고리의 다른 글

[Django] 계정정보 수정, 비밀번호 변경  (0) 2019.04.18
[Django] 계정 생성, 로그인, 로그아웃  (0) 2019.04.12
[Django] Image Upload  (0) 2019.04.11
[Django] Model Form  (0) 2019.04.10
Comments