티스토리 뷰
1. 일대 다 관계(1:N) => ForginKey를 부여
reporter(유저)
PK | |
id | username |
1 | john |
2 | neo |
3 | justin |
4 | ed |
5 | bring |
articles_article(게시글)
PK | ForginKey | ||
id | title | content | reporter_id |
1 | dfadf | dddd | 1 |
2 | aadsf | ffd | 2 |
3 | df | fasd | 1 |
4 | as | dff | 1 |
5 | fdff | assd | 4 |
2. 다대다 관계(N:M)
ex) 예약시스템. 의사와 환자 진료를 예약하는 시스템을 생각해보자.
의사
id (PK) | name |
1 | dr.cha |
2 | dr.john |
환자
id (PK) | name |
1 | 환자1 |
2 | 환자2 |
3 | 환자3 |
2개의 table을 어떻게 관리할까?(의사와 환자의 관계)
만약 1:N 처럼 FK 넣으면 환자가 의사를 2명 만나거나 변경 시 수정이 불가능하다.
따라서 별도의 table을 만드는 것이 핵심이다. 그리고 별도의 table에 추가가 발생하면 아래 부분에 추가 해 주면 된다.
Reservation
doctor_id | paticent_id |
1 | 1 |
1 | 2 |
2 | 3 |
2 | 2 |
추가 예약이 발생하면 아래에 행을 추가시켜서 넣어준다.
이제부터 위의 내용을 모델링을 해보자.
2-1. 단순 직관적 모델링
위의 내용을 그대로 models.py에 적어보자
class Doctor(models.Model):
name = models.CharField(max_length=10)
class Patient(models.Model):
name = models.CharField(max_length=10)
class Reservation(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
doctor.reservation_set.all()
patient.reservation_set.all()
2-2 중개 모델 활용
의사-환자들 /환자-의사들로 직접 접근을 하기 위해서는 ManyToManyField를 사용한다.
through 를 이용하고 reservation을 통해서, Doctor에 접근. 위와 단순 직관적 모델링과 같은데 ORM 조작만 차이가 난다.
class Doctor(models.Model):
name = models.CharField(max_length=10)
class Patient(models.Model):
name = models.CharField(max_length=10)
doctors = models.ManyToManyField(doctor,
through='Reservation')
class Reservation(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
doctor.patient_set
patients.doctors
중개 모델 중 반드시 역참조를 써야하는 상황
유저와 게시글, 좋아요누른 사람과 게시글의 관계를 설정시 게시글 클래스에 related_name 없이 정의를 하게 되면 역참조 이슈를 발생한다.
class Doctor(models.Model):
name = models.CharField(max_length=10)
class Patient(models.Model):
name = models.CharField(max_length=10)
doctors = models.ManyToManyField(doctor,
through='Reservation',
related_name='patients')
class Reservation(models.Model):
doctor = models.ForeignKey(Doctor, on_delete=models.CASCADE)
patient = models.ForeignKey(Patient, on_delete=models.CASCADE)
doctor.patients
patients.doctors
코드해석(ManyToManyField)
ManyToManyField를 적으면 자연스럽게 table을 하나 더 만들어 준다.
doctor - 의사와 연결을 시키고 patient는 doctor을 참조한다.
through - Reservation을 통해 탐색한다
related_name - 이걸 적으면 보통 through를 지운다. 역참조로 중개 클래스도 삭제해준다. 그 부분이 아래 코드. 그러나 중개 table이 필요한 경우도 있다. 예약날짜 같은 추가 정보가 필요하다면 table을 위 처럼 넣어준다.
2-3. 중개 모델 없이 설정
일반적으로 추가 필드 필요없이 id 값만 존재하는 경우는 아래와 같이 선언한다.
class Doctor(models.Model):
name = models.CharField(max_length=10)
class Patient(models.Model):
name = models.CharField(max_length=10)
doctors = models.ManyToManyField(doctor,
related_name='patients')
정리
중개모델이 필요 없는 경우는 특정 Class에 ManyToManyField 선언하자.
중개모델이 필요한 경우에는 중개 모델을 정의 후에 특정 class에 ManyToManyField에 through 옵션을 통해 조작하자.
그리고 ManyToMany에서는 복수형의 포현으로 반드시 related_name을 선언하자.
'Web > Django' 카테고리의 다른 글
[Django]데이터베이스관리(N:M)_팔로우 기능 구현(custom user) (0) | 2020.08.29 |
---|---|
[Django]데이터베이스관리(N:M)_좋아요 기능 구현 (32) | 2020.08.28 |
[Django]데이터베이스관리(1:N)_댓글 기능 추가하기 (0) | 2020.08.24 |
[Django]데이터베이스관리(1:N)_User와 Article (1) | 2020.08.23 |
[Django]사용자인증관리_회원탈퇴 (0) | 2020.08.16 |
- Total
- Today
- Yesterday
- TensorFlow
- read_csv
- 자료구조
- pandas
- nodejs
- typescript
- react autoFocus
- login
- BFS
- mongoDB
- Deque
- logout
- 클라우데라
- useHistory 안됨
- DFS
- useState
- NextJS
- Queue
- next.config.js
- django
- vuejs
- UserCreationForm
- Express
- react
- JavaScript
- 자연어처리
- error:0308010C:digital envelope routines::unsupported
- Vue
- nextjs autoFocus
- Python
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |