2019.05.27 장고 related_name 설정 방법
장고 related_name
장고에서 모델을 설정할 때 Foreign키를 설정해주고 뒤에 related_name을 설정해준다.
related_name을 설정해주는 것은 장고의 ORM기능을 활용하기 위해서이다.
하지만 이 related_name을 잘못 설정해주는 경우가 많다.
따라서 한 가지예를 들어가며 related_name에 대해 설멍해보려고 한다.
USER와 USER에 대한 Comment 설정
사용자들은 계속 생성될 수 있고 그 사용자 밑에 Comment(댓글)를 달아줄 수 있다고 생각해보자.
그럼 장고 모델의 형태는 이렇게 될 것이다.
User모델을 통해 User 객체는 1, 2, 3 지속적으로 생성될 것이고, (primary key)
Comment모델을 통해 Comment 객체 역시 지속적으로 생성 될 것이다. (foreign key)
여기에서 중요한 것은 Commnet모델에서 Foreignkey를 통해 User모델로 연결을 해놓았고
따라서 각각의 Comment들은 User_id를 통해 어떤 User의 커멘트인지 구분 할 것이다.
그럼 Comment의 모델을 한번 적어보자.
class Comment(models.Model):
User = models.ForeignKey(User, on_delete=models.CASCADE, related_name= ? )
단순히 위와 같이 Comment 모델을 만들어 준다고 하면 related_name에는 무엇이 들어가야 할까?
처음 내가 프로젝트를 진행할 때 나는 related_name에 너무나도 자연스럽게 user를 넣어주었다.
related_name이 무언가 Comment의 User를 사용할 때 연관된 이름으로 무엇을 쓸 것이냐고
해석하였기 때문에 필드명과 똑같이 설정해준 것이다.
하지만 내가 새롭게 알게 된 것에 따르면
위에 적어놓았다시피 related_name은 장고 ORM모델을 위한 것이며,
ORM모델은 쿼리문 없이 장고에서 데이터베이스와 소통하기 위한 것이다.
따라서, 만약에 내가 User 필드의 related_name을 user라고 해놓았을 경우
해당 User의 Comment를 불러오기 위해서는 어떻게 해야 할까?
comment = user.user.all() 이라는 이상한 상황이 발생한다….
위의 내용은 comment는 해당 유저객체의 comment달린 것의 all (모든 것) 이라는
것인데 내가 comment객체에서 user에 대한 foreignkey의 related_name을 user로 설정해놓아
user.user.all()이라는 이상한 ORM이 만들어버린 것이다.
따라서 몇 가지 related_name을 생성해 줄 때 알아야 할 것이 있다.
- 폴인키로 연결시켜 놓은 클래스에 related_name = comment라고 해놓으면 user.comment라는 것이 comment모델에 생기는 것이 아나리 comment가 참조하고 있는 user모델에 생긴다.
- 따라서 참조해준 객체 입장에서 related_name을 설정해줘야 한다.
따라서 위의 경우 다시 한번 Comment모델을 적어보면
class Comment(models.Model):
User = models.ForeignKey(User, on_delete=models.CASCADE, related_name= 'comment' )
라고 하는 것이 올바른 related_name을 설정해준 것이고 해당 유저의 comment를 모두 가지고 오고 싶을 때 사용할 ORM은 comment= user.comment.all()이 된다.