Atchapedia #3 - MovieDetailView

jinatra·2021년 9월 7일
0

Atchapedia

목록 보기
3/5
post-thumbnail

Atchapedia #3 - MovieDetailView


영화 이미지 (스틸컷) 추가

#2에서 진행했던 포스터 이미지를 제외하더라도, 왓챠피디아에는 스틸컷을 보여주는 '갤러리'가 따로 있고, 갤러리의 첫번째 사진을 페이지 상단에 출력시켜 준다.

ERD를 구성할 때, movie_id를 참조하는 images 모델을 생성하였었다.
path parameter로 movie_id를 가져오게 되면, 해당 영화에 할당된 이미지들을 출력하면 된다.


이미지 가져오기

내가 처음 생각했던 방법은 아래와 같다.

images 모델 안에 movie_id 데이터가 담겨있으므로, 해당 movie_id를 가지는 이미지 query set을 가져와 for loop을 돌려 하나씩 출력하면 된다.

POSMAN을 이용하여 데이터를 가져와보면 아래와 같이 출력이 된다.


역참조에 대한 이해 (_set 매니저)

이제 전체 코드를 봐보자

내가 코드를 짜고 나서 생각했던 것이, 이미 get된 movie_id와 일치하는 객체를 movie로 지정해줬으니까 저걸 이용할 수도 있겠다는 생각이었다.

허나 movie 객체는 Movie 테이블에서 가져와진 것이고, Movie 모델 안에는 image에 대한 데이터가 존재하지 않으니 우리는 역참조 되어 있는 images 테이블에서 데이터를 가져와야 한다.

이럴 때 _set 매니저를 사용할 수 있다.


_set 매니저

_set 매니저는 역참조를 하고자 할 때 사용한다.

아래 예시를 보면, a라는 변수에 1번 id를 가지는 영화의 객체를 담았다.

In [2]: a = Movie.objects.get(id=1)

In [3]: a
Out[3]: <Movie: Movie object (1)>

이제 이 a 영화 객체의 이미지를 불러오려면 _set 매니저를 사용하면 된다.

In [6]: a.image_set
Out[6]: <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x7fc089f9df10>

해당 이미지의 객체가 담긴 쿼리셋 형태로 불러오려면, .all()을 사용하면 된다.

In [7]: a.image_set.all()
Out[7]: <QuerySet [<Image: Image object (1)>, <Image: Image object (2)>, <Image: Image object (3)>]>

여기서 객체 뒤, _set 매니저 앞에는 가져오고자 하는 테이블의 class명을 소문자로 적어주면 된다.

예를 들어 위 테이블에서 우리는 ratings 모델과 wish_lists 모델이 movies 모델을 참조하고 있는 것을 볼 수 있으므로, _set 매니저를 사용하여 아래와 같이 불러올 수 있다.

In [21]: a.rating_set.all()
Out[21]: <QuerySet [<Rating: Rating object (1)>, <Rating: Rating object (40)>, <Rating: Rating object (79)>, <Rating: Rating object (118)>, <Rating: Rating object (157)>]>

In [22]: a.wishlist_set.all()
Out[22]: <QuerySet []>

wishlist 데이터가 아직 채워지지 않은 상태이므로, 빈 쿼리셋이 반환되는 것을 확인할 수 있다.


_set 매니저를 적용한 코드 리팩토링

위에서 배운 것을 적용하여, movie 객체와 역참조 관계에 있는 images 테이블에서 가져올 수 있다.

다만 이 경우엔 한 영화가 여러 이미지를 가지고 있을 수 있기에, comprehension (for loop)을 이용하여 불러오면 된다.

이렇게 되면 아래와 같이 코드를 바꿀 수 있다.


Participants 추가

영화에 참가하는 사람들은 크게 감독, 배우가 있고, 배우는 주연과 조연으로 각각 역할이 나뉘어 진다.

국민 영화 타짜의 경우 최동훈이 감독 역할을 맡았고, 조승우, 김혜수, 백윤식 등의 배우들이 주연, 김상호 등의 배우들이 조연을 맡았다.

한 영화엔 여러 사람이 참여하고, 한 사람이 여러 영화에 참여하므로 다대다 관계라고 볼 수 있다.
각 영화에서 사람들이 맡은 배역을 우리는 아래와 같이 중간테이블에서 role이라는 row를 추가하여 따로 지정해주었다.

이제 나는 각 영화에 참가한 사람들과, 해당 영화에서 어떠한 역할을 맡았는지에 대한 데이터를 가져올 것이다.


다대다 관계 이용

앞선 M2M 관계에 대한 블로깅에서 힌트를 얻어 코드를 짤 수 있었다.

중간 테이블을 이용하여 participants 모델에 접근하여 가져오는 방법이었다.

get으로 가져온 movie_id와 일치하는 중간 객체를 filter 쿼리를 통해 가져온 후, participants 모델로 가서 이름과 이미지를 가져오고 배역 데이터의 경우엔 그냥 바로 중간 테이블에서 가져오면 되는 것이다.





Take Away

참조와 역참조 관계에 대한 이해

약간은 애매모호했던 참조와 역참조 관계에 대한 개념이 어느정도 잡히기 시작한 것 같다.
사실 생각해보면 굉장히 간단한 개념이었는데, 이렇게 직접 몸으로 부딪혀가면서 직접 데이터를 뽑아보니 이해가 간다.


다대다 관계의 participant 데이터 추출 시 movie 객체 이용

이미지의 경우엔 movie 객체가 역참조하고 있었으므로 _set 매니저를 사용해서 바로 가져올 수 있었다.

위의 participant의 경우 다대다 관계인데, 어쩔 수 없는 role을 제외하더라도 nameimage_url과 같은 데이터들을 가져올 수 있을 듯 한데 어떻게 해야할 지 고민이 된다.

일단 위의 경우엔 role까지 같이 불러와야하므로 해당 방법이 맞다고 결론이 나온 듯 한데 계속 movie 객체 하나만 이용해서 name과 image_url 데이터를 가져올 수 있는 방법이 머릿속에서 떠나질 않는다.

생각보다 쉬울 것 같은데 어렵다..





참고
https://freeprog.tistory.com/55

profile
으악

0개의 댓글