Django | 정참조, 역참조

김민호·2021년 10월 4일
0

DJANGO

목록 보기
11/18
post-thumbnail

1. One to Many (1:N) 관계

주인 : 강아지
1 : N

  • 주인 1명이 강아지 여러 마리를 가지고 있을 수 있지만 강아지 1마리가 주인 여러명한테 속할 수는 없기 때문에
  • 강아지가 주인을 정참조 하고 있음 = (ForeignKey 속성으로 바로 접근)
  • 강아지 테이블에는 주인의 정보가 없지만 정참조를 통해 강아지테이블에서 주인 테이블로 가서 그 강아지의 주인을 알 수 있는 것

현재 데이터베이스에는 이렇게 되어 있고 "태훈"이와 태훈이의 강아지 3마리 바둑이, 멍멍이, 백구로 해보자

In [26]: dog1 = Dogs.objects.get(id=6)

In [27]: print(dog1)
Dogs object (6)

In [28]: print(dog1.name)
백구

In [29]: print(dog1.age)
13

In [30]: print(dog1.owner_id)
3
# owner_id는 원래 models.py에서 owner였지만
# FK속성으로 인해 자동으로 _id가 붙은 것
  • 먼저 Dogs라는 클래스를 통해 id=6인 인스턴스를 생성해서 dog1이라는 변수에 담는다. (=백구)
  • 그럼 dog1에는 백구 인스턴스가 담겨있는것
  • dog1의 name, age, owner_id를 가져올 수 있음
  • 그런데 owner_id는 Owners를 정참조 하고 있기 때문에 이를 통해서 주인의 정보들을 다 가져올 수 있는 것
In [32]: dog1.owner.name
Out[32]: '태훈'

In [33]: dog1.owner.email
Out[33]: 'taehoon@gmail.com'

In [34]: dog1.owner.age
Out[34]: 30

하지만 반대로 Owners는 Dogs를 역참조 하고 있으므로 바로 접근이 불가능하다. "태훈"이라는 주인을 가지고 있는 모든 강아지를 불러와보자

In [41]: owner1=Owners.objects.get(name="태훈")

In [42]: print(owner1)
Owners object (3)
  • 먼저 "태훈"이라는 이름을 가진 유저 인스턴스를 owner1에 담았다
  • Owners object (3) DB 테이블의 3번 id 인스턴스라는 것
  • 그럼 "태훈"이라는 인스턴스인 owner1의 강아지들을 바로 불러올 수 있을까?
  • owner1.dogs.all() 이렇게 바로 불러와버리면 오류가 난다

역참조를 불러오는 방법

1. [classname]_set

  • 이렇게 역참조를 하는 경우에는 [classname]_set 이라는 속성을 통해 접근할 수 있다
  • 이때 [classname]_set 대신 사용할 수 있는 것이 related_name 이다. 역참조 대상인 Owners 객체를 부를 이름. Owners 클래스를 정의할 때 정참조 하고 있는 Dogs 클래스의 인스턴스에서 어떤 명칭으로 거꾸로 호출 당할지 정해주는 이름인 것이다

  • 역참조를 하기 위해 Dogs 클래스의 owner 컬럼의 속성으로 related_name을 일단 aaa로 주었음

  • 여기서 related_name인 dogs로 가져오면 역참조 성공.
  • "태훈"이를 통해 "태훈"이를 fk로 갖고 있는 강아지들(인스턴스들) 전부를 불러올 수 있게 되었다
  • 추가적으로 related_name 속성을 이미 준 경우에는 _set 속성으로 불러올 시 AtrributeError가 난다

모든 Foreign Key에 related_name을 붙여줄 필요는 없다. 때에 따라, 참조하고 있는 객체 이름에 _set을 붙이는 것이 더 직관적인 경우가 굉장히 많기 때문이다.

2. Many to Many (N:N) 관계 ✍🏼

profile
개발자로서의 삶은 https://velog.io/@maxminos 에서 기록하고 있습니다 😀

0개의 댓글