N:1 or 1:N
한 테이블의 0 개 이상의 레코드가 다른 테이블의 레코드 한 개와 관련된 관계
Comment (N)- Article(1)
0개 이상의 댓글은 1개의 게시글에 작성될 수 있다.
1은 N에 대한 물리적인 정보를 가질 수 없다
Django를 활용한 댓글 모델 정의
ForeignKey()
한 모델이 다른 모델을 참조하는 관계를 설정하는 필드
- N:1 관계 표현
- 데이터베이스에서 외래키로 구현
댓글 모델 정의
- ForeignKey 클래스의 인트턴스 이름은 참조하는 모델 클래스 이름의 단수형으로 작성하는 것을 권장
- 외래키는 ForeignKey 클래스를 작성하는 위치와 관계없이 테이블의 마지막 필드로 생성됨
- ForignKey(to,on_delete)
- to : 참조하는 모델 class 이름
- on_delete: 외래키가 참조하는 객체(1)가 사라졌을 때, 외래키를 가진 객체(N)을 어떻게 처리할 지를 정의하는 설정(데이터 무결성)
- on_delete의 'CASCADE': 참조된 객체(부모객체)가 삭제 될 때 이를 참조하는 모든 객체도 삭제되도록 지정
생성된 댓글 테이블 확인
- 댓글 테이블의 article_id 외래 키 필드 확인
- 만들어 지는 필드 이름
- '참조 대상 클래스 이름' + '_' + 'id'
참조하는 클래스 이름의 소문자(단수형)로 작성하는 것이 권장 되었던 이유!!
댓글 생성 연습해보기
1. shell_plus 실행 및 게시글 작성
2. 댓글 생성
에러나는 방법
올바른 방법
comment.article = article
- comment.article_id = article.pk 표현으로 pk 값을 직접 외래 키 컬럼에 넣어 줄 수도 있지만 권장하지 않는다!!
클래스 변수명인 article로 조회 시 해당 참조하는 게시물 객체를 조회할 수 있다.
역참조
- N:1 관계에서 1에서 N을 참조하거나 조회하는 것(1 → N)
- 모델 간의 관계에서 관계를 정의한 모델이 아닌 관계의 대상이 되는 모델에서 연결된 객체들에 접근하는 방식
N은 외래키를 가지고 있어 물리적으로 참조가 가능하지만 1은 N에 대한 참조 방법이 존재하지 않아 별도의 역참조 키워드가 필요!!
참조(Comment → Article)
역참조(Article → Comment)
역참조 사용 방법
article.comment_set.all()
모델인스턴스.related manager(역참조 이름).QuerySet API
related manager
- N:1 혹은 M:N 관계에서 역참조 시에 사용하는 매니저
'objects' 매니저를 통해 QuerySet API를 사용했던 것처럼 related manager를 통해 QuerySet API를 사용할 수 있게 됨
related manager 이름 규칙
- N:1 관계에서 생성되는 Related manger의 이름은 "모델명 _set" 형태로 자동 생성됨
- 관계를 직접 정의하지 않은 모델에서 연결된 객체들을 조회할 수 있게 함
- 특정 댓글의 게시글 참조(Comment → Article)
- comment.article
- 특정 게시글의 댓글 목록 참조(Article → Comment)
- article.comment_set.all()
댓글 구현하기
1. 사용자로부터 댓슬 데이터를 입력 받기 위한 CommentForm 정의
2. detail view 함수에서 CommentForm을 사용하여 detail 페이지에 렌더링
- Comment 클래스의 외래 키 필드 article 또한 데이터 입력이 필요한 필드이기 때문에 출력되는 것
- 하지만, 외래 키 필드 데이터는 사용자로 부터 입력 받은 값이 아닌 view 함수 내에서 다른 방법으로 전달 받아 저장되어야 함
해결방법
- 출력에서 제외된 외래 키 데이터는 어떻게 받아와야 할까?
- detail 페이지의 URL을 살펴보면 path('<int:pk>/', views.detail, name='detail') 에서 해당 게시글의 pk 값이 사용되고 있음
- 댓글의 외래 키 데이터에 필요한 정보가 바로 게시글의 pk값
CommentForm의 출력 필드를 조정하여 외래 키 필드가 출력되지 않도록 하기
url 작성 및 action 값 작성, html 수정
에러 발생
article_id 값이 누락되었기 때문!!
save 메서드의 commit 옵션을 활용하여 해결!!
save(commit=False)
- DB에 저장 요청을 보내지 않고 인스턴스만 반환!!
댓글 read 구현
detial view 함수에서 전체 댓글 데이터를 조회
- 역참조 활용해서 댓글 정보를 context로 넘겨줌
댓글 DELETE
방법 1
url 추가
comments_delete view함수 생성
삭제 버튼 추가
방법 2
url 추가
comments_delete view함수 생성
삭제버튼 추가
참고
데이터 무결성
- 데이터베이스에 저장된 데이터의 정확성, 일관성, 유효성을 유지하는 것
- 데이터베이스에 저장된 데이터 값의 정확성을 보장하는 것
중요성
- 데이터의 신뢰성 확보
- 시스템 안정성
- 보안 강화
admin site 등록
Comment 모델을 admin site에 등록해 CRUD 동작 확인하기
댓글 추가 구현
1. 댓글이 없는 경우 대체 콘텐츠 출력
DTL의 'for empty' 태그 활용
2. 댓글 개수 출력하기
DTL filter - 'length' 사용
QuerySet API - 'count()' 사용
'Django' 카테고리의 다른 글
Many to Many Relationships 01 [Database] (1) | 2024.10.14 |
---|---|
Many to one relationships 2 [Database] (0) | 2024.10.11 |
SQL 02 [Database] (0) | 2024.10.10 |
SQL [Database] (0) | 2024.10.10 |
Authentication System 02 [Django] (0) | 2024.10.02 |