2020.09.15_django_관계 표현 modelfield_정리 노트
오늘은 저번 포스팅에서 잠시 언급했던 ManyToManyField 와 함께 관계를 정의하는 필드를 알아보고 활용...할 수 있도록 메모메모 공부공부
다대일관계 ( Many-to-one Field )
한 테이블에 두 개 이상의 레코드가 다른 테이블에 있는 하나의 레코드를 참조할 때 이 두 모델의 관계를 다대일 관계라고 한다.
쉽게 예를 들면 게시물 하나당 여러 개의 댓글이 달릴 때 댓글 하나하나는 pk (primary key)를 갖지만, 참조하는 게시물의 ID는 한 게시물의 ID를 갖는다. 이 참조하는 ID를 우리는 Foriegn Key ( 외래키 ) 라고 하는 것!
쉽게 여기서 똥땅똥땅 만들어보면
Post table
id | post_name |
1 | free_post |
Comment table
id | comment | post_id |
1 | hello | 1 |
2 | great | 1 |
3 | good | 1 |
이렇게 Comment table 에서 첫번째 id는 고유의 댓글의 값으로 pk라고 볼 수 있지만, 참조하는 게시물의 아이디인 post_id 는 여기서 외래키인 fk라고 보면 되는 것!
( pk는 이 포스팅에서 다뤘음. )
또한 장고에서 모델로 써줄 때
class Post(models.Model):
필드 이름 = models.필드 (CharField, TextField 등등.. )
class Comment(models.Model):
필드 이름 = models.ForeignKey (Post, on_delete = 삭제 옵션 )
>>> 필드 이름 = models.ForeignKey(연결모델, on_delete = 삭제 옵션 )
이러한 형태로 써주어야 하는데, 여기서 on_delete 옵션은 필수다.
on_delete
만약 참조하는 모델의 데이터가 삭제 되었을 시 ( 여기서는 Post ) , N 쪽의 ( 여기서는 Comment ) 데이터를 어떻게 처리할 지에 대한 설정.
옵션
CASCADE : 참조하는 모델 ( Post ) 의 데이터가 삭제 되면, 참조하고 있는 모델 ( Comment ) 의 모든 데이터를 같이 삭제 해줌.
PROTECT : 참조하는 모델 ( Post ) 의 데이터가 삭제가 되지 않도록 보호. 삭제를 시도하게 되면, ProtectedError 를 발생 시킴.
SET_NULL : 참조하는 모델 ( Post ) 가 삭제 되면, Comment 모델의 값이 null이 됨. 여기서에서는 null = True 옵션이 있을 때만 가능.
SET_DEFAULT : 여기서도 Post 가 삭제 되면, Comment 값이 default 로 값이 대체 됨. 여기서도 default 옵션이 설정되어 있을 때만 가능.
SET : 함수에 값이나 호출 가능한 객체를 전달할 수 있고, Post 가 삭제 되면, 함수의 결과에 따라 Comment를 호출한 결과로 외래키 필드를 채움.
DO_NOTHING : 아무 것도 하지 않지만 db 에서 오류가 발생할 수 있음.
일대일 관계 ( One-to-one Field )
한 테이블의 하나의 레코드가 다른 테이블의 단 하나의 레코드만을 참조할 때 이 두 모델간의 관계를 일대일 관계라고 한다. 이 관계는 어떤 테이블을 구조적으로 확장 시킬 때 유용하게 쓰인다.
예를 들어 user 모델에서 커스텀을 해주고 싶거나 확장하고 싶을 때 쓰는 profile 모델을 만들 때 주로 쓰인다.
User table
user_id | user_name |
1 | korin |
Profile table
user_nickname | user_impormation |
korinkorin | korin likes purple. |
이렇게 Profile 모델에서 User 테이블의 user_name 을 불러와서 확장 시키고 싶을 때, OneToOneField 를 써준다.
class User(models.Model):
필드이름 = models.필드
class Profile(models.Model):
필드이름 = models.OneToOneField (User)
필드이름 = models.필드
필드이름 = models.필드
>>>>>필드이름 = models.OneToOneField (대상 모델)
확장해줄 내용의 필드
여기서 OneToOneField의 값은 반드시 고유한 값이어야 한다.
재귀적 관계 ( Recursive Field )
한 테이블의 레코드들이 같은 테이블의 다른 레코드들과 관계를 형성하는 것을 재귀적 관계라고 한다.
예를 들어 교실안의 학생들의 담임 선생님을 참조하려 할 때 모두 같게 된다.
Classmate table
techer | student | teacher_id |
1 | korin | 1 |
2 | purple | 1 |
여기서 선생님 필드는 Class table의 기본키인 teacher 을 참고한다. 그리고 코드가 정의 되는 시점에서
class ClassMate(models.Model):
student = models. 필드
teacher = models.ForeignKey( 'self', on_delete 옵션 )
재귀적 관계는 아래와 같이 연결대상 위치인자로 문자열로 감싼 'self' 를 전달하여 설정할 수 있다.
다대다 관계 ( Many-to many Field )
드디어......나왔다...... 흑흑 차근차근 정리
한 테이블의 하나 이상의 레코드가 다른 테이블의 하나 이상의 레코드를 참조할 떄 두 모델간의 관계를 다대다 관계라고 한다.
이를 표현하기 위해서는 두 테이블 사이의 관계를 표현하기 위해 참조 정보를 담은 새로운 테이블을 생성하게 됨.
장고에서 Post 에 Tag를 생성할 때 주로 쓴다.
Post table
id | Post_name |
1 | hi |
2 | hello |
Tag table
id | Tag_name |
1 | django |
2 | python |
Post-tag table
id | Post_id | Tag_id |
1 | 1 | 1 |
2 | 2 | 2 |
Post_tag table은 두 테이블 간의 다대다 관계를 나타내주는 중개 모델으로, 자동으로 테이블이 생성된다.
여기서 포스트모델 테이블과 태그모델 테이블의 Id 필드를 각각 참고해서 Post_id, Tag_id 를 외래키 필드로 가지게 된다.
방법 1
class Post(models.Model):
필드이름 = models.ManyTomanyField('Tag')
class Tag(models..Model):
필드이름 = models.필드
방법 2
class Post(models.Model):
필드이름 = models.필드
class Tag(models..Model):
필드이름 = models.ManyTomanyField(Post)
이렇게 방법이 총 2가지가 있고 위에 모델에서 아래에 있는 모델을 지정할 때에는 문자열로 표현해주고, 밑의 모델에서 위에 있는 모델을 지정할 때는 모델이름을 써주면 된다.
다대다 관계에서는 두 테이블 간의 고나계를 표현하는 테이블이 자동으로 생성 되지만, 개발 시 직접 중개 모델을 생성해줄 수도 있다. 이 떄 추가정보를 담은 필드들을 중개 모델에 삽입할 수도 있다.
형태는
class 중계 모델이름 (models.Model):
필드 = models.ManyToManyField(through='관계 모델')
이렇게 ManyToManyField 의 옵션으로 through로 생성해주면 된다.
중개 모델의 제약
중개 모델을 직접 생성할 때는 두 테이블을 각각 참조하는 외래키 필드를 명확히 선언해주어야 한다.
또한 다대다 관계의 모델을 참조하는 외래키가 반드시 각각 하나하나씩 연결되어야 한다.
오늘은 내가 직접 써보면서 찾아본 것은 아니고 개념들을 구글링 하면서 내가 보기 쉽게 정리만 한건데, 사실 직접 써보지 않으면 잘 모를 것...흑 하지만 장고 댓글 기능을 구현하기 전에 한번 정리가 혼자 필요한 것 같아 이것저것 나름 이해해보면서 써본 포스팅! 그러면 다음에.. 댓글로 직접 써보면서 다시 정리하러 넘어오게씀 오늘 포스팅 끝!
'django' 카테고리의 다른 글
2020.09.19_django_class CRUD (0) | 2020.09.19 |
---|---|
2020.09.17_django_댓글 구현 (0) | 2020.09.17 |
2020.09.14_django_Admin import, export (4) | 2020.09.15 |
2020.09.08_django_category 나누기 (2) | 2020.09.09 |
2020.09.02_django_template 상속 (0) | 2020.09.03 |
댓글