앞선 프로젝트 블로깅에서 후기를 적을 때, 다대다 관계에 있는 participant의 데이터를 movie 객체를 이용해서 가져오는 것에 대해 고민했었다.
혼자 shell에서 계속 쳐본 결과, 가능하다는 것을 알 수 있었다!!!
시작은 models.py를 보는 것으로 시작되었다.
Movie
모델을 보게되면, 다대다 관계에 있는 participant 모델을 의식하여 ManyToMany
필드를 부여하였다.
이것이 어떤 장점이 있냐면, 데이터를 불러올 때 중간 테이블을 사용하지 않고 불러올 수 있다.
아래 예시를 보면, 영화 기생충을 변수 a
에 담았다.
In [38]: a = Movie.objects.get(id=3)
In [39]: a
Out[39]: <Movie: Movie object (3)>
In [40]: a.title
Out[40]: '기생충'
이때, ManyToMany
필드에 지정해준 이름을 쿼리로 입력하게되면 데이터가 불러와지고, .all()
을 사용하면 쿼리셋 형태로 반환되는 것을 볼 수 있다.
In [46]: a.participant
Out[46]: <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager at 0x7fc09809a670>
In [47]: a.participant.all()
Out[47]: <QuerySet [<Participant: Participant object (19)>, <Participant: Participant object (20)>, <Participant: Participant object (21)>, <Participant: Participant object (22)>, <Participant: Participant object (23)>, <Participant: Participant object (24)>, <Participant: Participant object (25)>, <Participant: Participant object (26)>, <Participant: Participant object (227)>]>
In [48]: a.participant.all()[0].name
Out[48]: '봉준호'
쿼리셋으로 불러와졌지만, 하나 이상의 데이터가 입력되었기에 Json 식으로 가능하게 해줘야 한다.
아주 간단하게 iterate을 통해 list에 담아주면 된다.
처음에 iterate을 돌려줄 쿼리셋, movie.participant.all()
에서 임의의 변수 participant
를 지정해준 후 그에 해당하는 데이터들을 담으면 되는 것이다.
앞선 질문이 머릿속에서 떠나질 않아서 shell에다가 무작정 쳐보다가 발견하게 되었다.
지금은 기뻐서 블로그에 쓰지만, 나중에 가서 비슷한 상황에 가서 다시 처했을 때 과연 내가 올바르게 사용할 수 있을까라는 걱정이 앞선다.
결국 답은 계속 사용해보면서 체득하고 익숙해지는 수 밖에는 없을 것 같다.
초기 모델링의 중요성을 또한번 느끼게 되었다.
Movie
모델에 ManyToMany
필드를 주지 않고, Participant
모델에 ManytoMany
필드를 주게 되었다면 아마 가져오지 못하고 중간 테이블을 이용할 수 밖에 없지 않았을까 싶다.
M2M 관계에서 ManyToMany
필드를 어느 모델에 줄것인가도 정말 중요하게 생각해야 할 것 같다.
결국 더 많이 선언하고, 데이터를 가져오게 될 객체가 있을 모델에 주는 것이 맞는 듯 한데.. 정답은 모르겠다.