TIL DAY 17 || Python Django related_name

TK·2021년 3월 8일
1

TIL

목록 보기
22/55

인스타그램 좋아요 기능을 클론하던 중 ManyToMany 관계를 이용해서 모델링을 하다가 related_name 이 왜 필요한지에 대해 알게 되는 계기가 있었다.

다음은 게시물 모델 Posting 이다.

  • Posting 모델의 컬럼은
    created_time, content, user, liked_users 로 구분이 되어있다.

  • Posting 모델은 User 모델을 one-to-many 관계로 참조하고 있다.

문제는 여기서 발생했었다.

Posting 과 User 모델을 many-to-many 관계로 이어주기 위해 Posting 모델에서 User 모델을 liked_users 라는 컬럼을 통해 참조했었다. 이 때는 related_name 을 명시해 주지 않은 상태였는데 이대로 makemigration 을 수행하니까 다음과 같은 오류가 났다.

Reverse accessor for 'Posting.user' clashes with reverse accessor for 'Posting.liked_users'

알고보니, 하나의 모델에서(Posting) 여러 컬럼이(user, liked_users) 다른 동일한 모델(User)을 참조할 때 역참조 접근을 위해 쓰는 <User instance>.posting_set 의 이름이 겹쳤기 때문이였다.

User 인스턴스를 만들어서 <User instance>.posting_set 으로 접근해야 한다. User 객체 자체로 하면 안된다.

Reason for reverse accessor Error

User 모델에 연결된 Posting 을 user fk 를 통해 역참조하기 위해 원래는 <User instance>.posting_set 을 통해 접근했다.

하지만 Posting 모델에 User 를 연결한 liked_users 가 추가되면서 User 에서 Posting 을 역참조할 수 있는 방법이 두가지가 생긴 것이다.

  1. user fk 를 통해
  2. liked_users fk 를 통해

Posting 에서 정참조하는 fk 에 related_name 을 설정해주지 않았을 때는 User instance 에서 posting_set 으로 접근하면 되지만

지금은 Posting 필드 두개에서 User 를 참조하고 있기 때문에, User 에서 Posting 을 어떤 fk 를 통해 역참조 해야할지 모른다.

<User instance>.posting_set 은 user fk 을 이용해 참조 한 것이다.

liked_users 필드에 related_name 을 설정해주면, <User instance>.<related_name> 으로 User 에서 Posting 으로 역참조가 가능해진다!

related_name='liked_postings' 으로 가정해보자.

  1. 어떤 유저가 자신이 게시한 모든 포스팅을 보고싶다 ?
    --> <User instance>.posting_set

  2. 어떤 유저가 자신이 좋아요 한 모든 포스팅을 보고싶다 ?
    --> <User instance>.liked_postings

fk (외래키) 에 related_name 을 지정할 땐 보통 <자기가 속하는 테이블 명의 복수> 마지막에 적어줘서 어떤 모델이 이 테이블을 역참조 할 때 어떤 테이블을 참조해서 어떤 값을 가져오는지 명확히 하기 위해서다.

user.liked_postings
유저가 좋아요한 포스팅 전부

profile
Backend Developer

0개의 댓글