[ToyPJ/Python] django 로 인스타그램 만들기 - 10 댓글, 좋아요, 북마크 모델 만들기
지금까지 나는 Feed 테이블, User 테이블을 만들어서 사용했다. Feed 테이블은 피드 화면을 표시하기 위해 필요한 필드들을 저장한 곳이고, User 테이블은 회원가입, 로그인 사용자 정보를 표시하기 위한 테이블이다. 이제 좋아요, 댓글, 북마크 기능을 만드려고 하는데 이것은 피드 테이블에 영향이 가지 않게 따로 만들어야 한다. 즉, 하나의 피드를 구성하는 데에는 Feed 테이블, 댓글 테이블, 좋아요 테이블, 북마크 테이블 이렇게 최소 4개의 테이블이 필요하게끔 테이블을 따로 만들어주려고 한다.
기존에 views.py에서 main.html에 feed_list를 내려줄 때, Feed 테이블에서도 데이터를 찾고 User 테이블에서도 데이터를 찾아서 내려줬는데, 마찬가지로 Reply 테이블, Like 테이블, Bookmark 테이블을 추가로 만들어서 views.py에서 main.html에 내려줄 수 있게 소스를 수정 및 작성해주면 된다.
📌 01. 새로운 모델 만들기(댓글, 좋아요, 북마크 테이블)
피드를 구성하는 데에 필요한 새로운 모델들을 만든다. content/models.py에 만들면 된다. 좋아요/북마크를 누르거나 취소할 때 값을 각각 True, False로 주기 위해서 BooleanField를 사용했다.
📌 02. 댓글 달기 기능 만들기
이제 댓글 달기 기능부터 하나씩 만들어보도록 하자. 댓글 달기 기능을 만들 때에 주의할 점이 있는데 만약 피드가 여러 개일 때 댓글을 쓰고 게시 버튼을 누르게 되면 해당 피드의 feed_id와 일치하는 피드에 댓글이 달아지도록 만들어야 된다는 점이다.
이렇게 하려면 "게시" 버튼을 눌렀을 때 feed_id가 무엇인지 알아야 한다. 다시 main.html에서 각 피드의 "게시"에 해당하는 feed_id를 만들어주기 위해 아래와 같이 수정한다.
하지만 그 전에, 이 feed_id가 무엇인지 뷰에서 알려줘야 된다.
이렇게 수정해주고 새로고침을 해주게 되면 아무런 변화가 없어보이지만 사실 변화가 생겼다. 개발자 도구를 실행시키고 게시 버튼을 찍어보면 각 피드에 따라 feed_id가 다르게 지정된다.
그렇다면 이제 각 피드의 "댓글 달기" 창에도 "이 피드에 댓글 달고 있어~~" 라고 id를 지정해줘야 한다.
피드가 여러 개이다 보니 댓글이 어떤 피드에 달린 댓글인지 구별할 수 있는 방법이 필요하기 때문에 위와 같은 방법을 사용했다. 그렇다면 이제 "게시"에 class를 만들고, 그 class를 클릭했을 때 어떤 이벤트가 발생하도록 제이쿼리를 작성하면 된다.
소스 작성이 완료되었다면, 브라우저로 돌아와 댓글을 작성해보자. "댓글 달기..." 입력창에 댓글을 입력하고 게시 버튼을 누르면 해당 피드에 댓글이 정상적으로 작성된다. 이 때, 위에서 작성한 ajax를 살펴보면 함수가 complete 되었을 때 location.replace("/main")으로 이동하게 되어있다. 그런데 만약, 전체 화면을 새로고침 해주지 않고 댓글만 업로드되도록 하고 싶다면 다시 ajax를 써주면 된다.
먼저, 피드 댓글 조회 창 상위에 새로운 <div>를 만들고 id를 지정한다. 즉, 특정 피드에 해당하는 댓글들의 모임의 id를 지정하고, 댓글 추가 시 그 댓글들의 모임에 새로운 댓글을 추가시켜주면 되는 것이다.
로그를 찍어보면 각 피드별 댓글 조회 창 id가 다르게 찍히는 것을 확인할 수 있다.
이제 제이쿼리를 사용하여 각 피드 id에 해당하는 부분에 <div> 생성하는 소스를 아래와 같이 작성하면 된다. 함수가 성공했을 경우 <div>가 생성이 되고, 함수가 완료되면 댓글 입력창이 초기화될 수 있도록 소스를 작성하였다.
📌 02. 좋아요 기능 만들기
좋아요 모델은 앞에서 이미 만들었다. 댓글 달기와 마찬가지로 좋아요를 누르면 피드 아이디가 올라오고 세션 정보에서 이메일을 끌어 오고, 처음 누르게 되면 True, 다시 누르게 되면 False가 되도록 작성하면 된다.
뷰에서 is_like가 True인 feed_id의 수를 count()함수로 세서 like_count에 저장한다.
이제 feed_list에 저장된 like_count개수 만큼 피드에 좋아요를 표시할 수 있도록 html을 수정해주면 된다.
브라우저에 잘 적용되는지 직접 db.sqlite3에 값을 넣고 한 번 확인해보자.
브라우저에서 정상적으로 좋아요 개수를 받아오는 것을 확인할 수 있다!
DB에 is_like필드를 true로 했을 때 true한 개수만큼 피드의 좋아요가 늘어나는 것을 확인했다. 그렇다면 이제 특정 피드에 좋아요를 눌렀는지 안 눌렀는지를 알 수 있어야 한다. 이를 통해 좋아요 누른 상태에서 한 번 더 클릭할 시 좋아요가 취소되는 기능을 구현할 수 있다.
먼저, 다시 뷰로 돌아와 사용자(세션 정보에 들어있는 이메일)가 피드 아이디에 대해서 좋아요를 누른 것이 exists하다면 is_liked 값에 True가 들어갈 수 있도록 작성한다.
그 다음, 좋아요를 눌렀을 때 하트가 채워지도록 html을 수정한다. feed(feed_list의 for문 내 변수)의 is_liked가 True(좋아요 눌린 상태)이면 꽉찬 하트, 그렇지 않다면 빈 하트가 화면에 표시되도록 하는 소스이다.
좋아요 누른 여부(is_liked)에 따라서 하트를 다르게 했다면, 좋아요 버튼을 실제로 눌렀을 때 화면에 표시되는 하트가 달라지도록 해야한다. 특정 동작(버튼 클릭)을 통해 브라우저를 변화시키고 싶은 것이므로 역시 제이쿼리를 활용하면 된다.
브라우저에서 직접 좋아요를 누르고 취소하는 것이 가능해졌다.
화면에서 바꾸는 것은 구현했으니 이제 좋아요를 눌렀을 때 ajax로 올려야 된다. 올릴 때 어떤 것을 올리면 되는지 아까 작성한 뷰에서 참고해보자. 좋아요 테이블에는 feed_id, is_like, email 세 개 필드가 필요한데 이것을 데이터로 받기 위해 ajax로 feed_id와 favorite_text를 올리면 된다.
좋아요 버튼에 feed_id를 지정해주자.
이제 ajax를 작성하면 된다. ajax를 통해 실행할 url도 만들어준다.
이제 DB에서 좋아요가 잘 올라가는지 확인해보자.
📌 03. 북마크 기능 만들기
북마크 기능 만드는 것은 좋아요 기능 만드는 것과 완전히 동일하다.
📌 04. 프로필 화면 만들기
이제 프로필 화면을 꾸며보기로 하자. 프로필 화면에는 "내 게시물, 좋아요, 북마크" 탭에 항을 표시하려고 하고 각 탭에 해당하는 피드 이미지가 한 줄에 3개씩 표시되도록 만들 예정이다.
이것을 구현하기 위해서는 각 탭을 눌렀을 때 해당하는 피드 리스트를 화면에 내려주면 되고, 역시 뷰에서 어떤 데이터를 내려줄지 작성한다. 아래는 어떤 방식으로 데이터를 뽑아서 내려줄지 정리하였다.
- feed_list : 세션 정보에 있는 이메일을 가져와서, feed_list에 내가 쓴 피드 전체를 가져온다.
- like_list : 내가 좋아요를 누른 feed_id를 리스트에 담는다.
- like_feed_list : id__in=like_list를 통해 like_list 내의 요소를 id로 받고, 그 id를 내려준다.
- bookmark_list : 내가 북마크한 feed_id를 리스트에 담는다.
- bookmark_feed_list : id__in=bookmark_list를 통해 bookmark_list 내의 요소를 id로 받고, 그 id를 내려준다.
이렇게 뷰를 작성해주었다면 어떻게 각 탭에 해당하는 피드 리스트를 브라우저에 표시할 수 있을까? html에 default로 "내 게시물"만 표시하고, 제이쿼리를 통해 각 탭 클릭 시 보여주는 피드 리스트를 다르게 해주면 된다.
먼저 html에 내 게시물 탭에 해당하는 피드 리스트를 보여주기 위한 소스를 작성한다. 상위 div의 width를 942px로 주고 flex:wrap 속성을 통해 flex아이템(이미지)들을 복수의 행으로 표현할 수 있도록 한다. 하위 div에 피드 리스트에 있는 요소의 개수만큼 반복을 수행하여, 피드 이미지를 media폴더에서 불러와서 300px*300px 크기의 이미지로 화면을 채울 수 있도록 소스를 작성한다.
작성을 완료하면 여러 개의 피드가 아래처럼 브라우저에 표시된다.
이제 좋아요, 북마크 탭도 html을 작성해주면 된다. 내 게시물 탭과 작성 방법은 동일하나, default로는 내 게시물에 해당하는 피드 리스트만 보여줘야 하므로 display: none 속성을 줘서 숨긴다.
이제 각 버튼에 id를 지정하고, 내 게시물, 좋아요, 북마크 탭 클릭시 피드 리스트를 내려주는 소스의 최상위 div에도 id를 지정하여 제이쿼리를 통해 각 버튼을 클릭했을 때 어떤 항목을 보여주고(display: flex) 어떤 항목을 숨길지(display: none) 작성한다.
https://cholol.tistory.com/548
이 게시물의 모든 저작권은 마이쮸(mychew__)님께 있으며, 저는 오직 학습과 기록을 목적으로 포스팅한 것임을 알려드립니다.
좋은 강의 컨텐츠를 제공해주신 마이쮸님께 감사의 말씀 드립니다. (_ _)