모든 관계가 N:1 이면 좋겠지만 N:1로는 커버할 수 없는 관계도 존재한다.
만약 종합병원에서 진료 예약 시스템을 만들어야한다고 가정하자. 한 명의 의사는 여러 환자의 진료 예약을 받을 수 있고, 한 명의 환자 또한 여러 의사의 예약을 신청할 수 있다. 동시에 예약을 남길 수 있다면 Foreign Key 자리에 1, 2 와 같은 값이 들어가야하는데, 이는 DB 구조상 불가능하다. 이를 해결하기 위해서는 예약 테이블(중개 모델)을 만들고 ManyToManyField를 사용하는 것이다. 그럼 좋아요 기능을 구현하러 가보자.
기존의 게시물 작성에서는 Article - User는 N:1 관계였지만 좋아요 기능에서는 Article - User는 M:N 관계이다. 해석해보면 게시글은 회원으로부터 0개 이상의 좋아요를 받을 수 있고, 회원은 0개 이상의 게시글에 좋아요를 누를 수 있다.
모델 관계 설정 - ManyToManyField 작성
에러 발생 -> related_name 사용
여기서 에러가 발생하는 이유가 중요하다.
현재 user의 입장에서는 이미 article과 N:1 관계를 맺고 있는데
좋아요 기능을 넣기 위해 다시 article과 M:N 관계를 부여했다.
그럼 user.article_set을 통해 역참조할 대상이 충돌하게 된다.
좋아요한 게시글을 보여줄 것인가? 작성할 게시글을 보여줄 것인가?
그래서 이를 해결하기 위해 ManyToManyField의 두번째 인자에 related_name을 사용하여 이름을 바꿔주자.
우린 Article과 User와의 관계에서 좋아요 기능을 추가함으로써 참조와 역참조 키워드를 정리해두자.
팔로우 기능을 만들기 위해 먼저 프로필 페이지를 만들어 주자.
url -> view -> template
<참고> ManyToManyField의 인자 해석
'self' : 유저와 유저와의 관계이므로 자기 자신을 모델로 삼는다.
symmetrical : 대칭이라는 의미로 한 명이 팔로우하면 다른 사람이 자동으로 맞팔 되는 건 자연스럽지 않으므로 False로 설정
Migration
url
view
template
<참고> .exists() 메서드
QuerySet에 결과가 포함되어 있으면 True, 없다면 False를 반환, 큰 QuerySet에 있는 특정 객체 검색에 유용