※ 개인 기록용으로 남겨놓는 첫 팀 프로젝트 - 정리x 우왕좌왕 기록. 시간이 남아돌 때만 볼 것.
프로젝트 요구 명세
: index.html - 팀 소개 대문 페이지 자유 형식 하나
app.py - 댓글 Ajax 요청을 보내고 받는 서버 하나
댓글 보여주기가 가능하도록.
각 개인 페이지로 이동이 가능하도록.
개발 기간
: 11/16(수) ~ 11/18(금)
일주일 중 약 3일
사용 기술/언어
: CSS, HTML, JavaScript(JQuery, Ajax)
mongoDB, Python(Flask)
초안 :
팀 회의 하면서 혼자 끄적여 본 초안:
과도기 :
결과
제출한 버전 ( =Initial commit 때의 상태 ):
내가 한 일 : 맨 밑에 방명록(댓글)을 출력하는 기능 + 댓글 여닫기 버튼 + 최신순 과거순 정렬 기능과 버튼 추가
1. 코멘트 시간순 정렬하기
메인 페이지에서 코멘트 불러오기 기능을 맡아 시간 순서대로 정렬하는 건 구현했다.
- index.html에서 <script>태그 안에, 제일 처음 렝더링 완료되면 ‘댓글 한 번 불러와라’ 이걸 살려두면 포스트를 할 때마다 페이지가 새로고침되면서 알아서 새 댓글까지 보여줄 것이고 ‘댓글 보기’ 버튼은 ‘댓글 새로고침’ 버튼이 되어야 할 것이다. 아니면 ‘댓글 보기’버튼에는 아예 GET으로 불러오는 기능을 없애버려도 되겠다. 뭔가 변경이 생긴다면 알아서 페이지가 새로고침 되면서 댓글이 쫙 보일 테니까.
지금 있는 ‘댓글 보기’와 ‘닫기’ 버튼을⇒ ‘댓글 최신순 정렬’, ‘댓글 과거순 정렬’, ‘닫기’ 버튼으로 나눠볼까? ⇒ 그리고 가능하다면 최신순과 과거순 정렬 버튼을 하나로 합치는 것이다.
- 준호님과 메인 페이지 댓글 기능 완성 회의를 하면서 인사이트를 많이 얻었다ㅠㅠ
흐름:
- 여러 DB에서 댓글을 불러온다고 하더라도 작성된 시간 순서대로 (섞여서) 화면에 출력되게 만들었다.
app.py에서 DB들의 댓글을 정렬해서 보낸 나의 방식:
# app.py에서 GET 함수: comments.sort(key=lambda k: ("time" not in k, k.get("time", None))) # comments = 여러 DB에서 가져온 댓글 데이터 리스트를 모두 더한 것.
index.html쪽에서 댓글을 정렬한 준호님의 방식:
// index.html에서 POST 함수: let time = new Date().toLocaleString() // '2022. 11. 17. 오후 3:01:39' ... // 그리고 ajax POST 요청시 저 시간 변수를 data에 넣어서 보내고, app.py쪽에서는 그대로 받아서 DB에 저장함.
- 기왕 시간 데이터도 댓글마다 같이 넣은 것, ‘작성 시간’도 화면에 같이 출력되게 했다.
나: 자바스크립트 쪽에서 어떻게 시간 데이터를 출력할지의 문제에 봉착
// index.html에서 GET이 받아오는 시간(time) 데이터: "Wed, 16 Nov 2022 20:27:24 GMT" // 이걸 어떻게 예쁘게 출력해내느냐는 더 고민해봐야 하는 문제였음.
준호님: 간-단
// index.html에서 GET이 받아오는 시간(time) 데이터: "2022. 11. 17. 오후 3:01:39" // 저장한 그대로 다시 찍어내주면 되므로 간단하고, 모양새도 예쁘다.
- 사용자가 원하면 최신순으로도 댓글을 정렬해서 볼 수 있도록 외부(화면에) 버튼을 만들자는 의견이 나왔다.
나: 부트스트랩 버튼으로 간단히 구현해 봄
- “댓글 과거순 보기”
- “댓글 최신순 보기”
- “닫기”
이렇게 세 버튼이 있고, 앞의 두 버튼은 누를 때마다 새로 GET요청을 가져온다.
준호님: (리뷰 전 미공개)
- 최신순/오래된 순 정렬 버튼을 두 개로 만드느냐 하나로 합치느냐의 주제에서 두 개 그대로 놔두자는 쪽으로 갔고 (이게 더 간단하고 + 뉴스 페이지 같은 곳에서도 ‘최신순’ ‘오래된 순’, ‘인기순’ 같은 버튼을 따로 두는 경향이어서),
- 내가 만든 건 두 버튼을 누를 때마다 서버에서 GET으로 불러오면서 현재 화면에 보이는 댓글 업데이트도 한 번씩 해주는 방식이었는데, 어차피 처음 페이지에 들어오거나 새로 댓글을 달았을 시 페이지가 새로고침되면서 댓글을 그려주게 구현해 놓은 상태이므로 정렬만 바꾸는 데 굳이 댓글을 ‘업데이트’해줄 필요가 없었다. GET요청도 낭비되므로, 두 버튼을 누를 땐 GET 요청 없이 정렬만 달리해주는 방법을 고안하기로 했다.
나: 난리남. GET 없이 정렬하기 위해 고난의 길을 가고 있었음 (스압주의)
먼저 나는 app.py쪽에서 datetime()을 써서 코멘트 일시를 저장했었는데, 이게 그냥 백에서부터 시간순 정렬해서 프론트로 보내주는 건 간단한데, 프론트에서 또 이 시간 데이터로 정렬을 해보려고 할 땐 “파이썬 날짜 객체” ⇒ “자바스크립트로 오면 문자열” 이렇게 되는 문제가 있었다.
- 우리 댓글은 div태그로 이루어져 있으므로, 처음에 “jquery div sort” 등으로 검색해보았다:
$("div.process-result").html($('div.process-result div.status-box').sort(sortLiElements)); function sortLiElements(a,b) { return parseInt($(b).data('time')) - parseInt($(a).data('time')); } <div class="process-result"> <div class="status-box blue" data-time="20210215171439"> <p class="title">신청 정보 수정</p> </div> <div class="status-box blue" data-time="20210215170344"> <p class="title">신청등록</p> </div> </div>
- 그래서 저 비교 함수 sortLiElements()를 쓰려면 두 시간 데이터가 뺄셈이 가능하도록 만들어야 했다. 그런데 앞서 언급한 것과 같은 문제가 있었음:
// 파이썬에서 datetime.datetime.now()로 생성한 시간 데이터 타입&모양새 : <class 'datetime.datetime'> 2022-11-16 20:27:24.768000 // 자바스크립트가 받아오면 (타입&모양새) : string Wed, 16 Nov 2022 20:27:24 GMT
- 그래서 시간 데이터를 app.py쪽에서 Int로 가공해서 넘겨주는 방식을 찾아보았다:
dt = datetime.datetime.now() # => datetime.datetime(2022, 11, 17, 13, 1, 40, 639404) seq = int(dt.strftime("%Y%m%d%H%M%S")) # => 20221117130140
- 이제 두 숫자를 크기 비교할 수 있게 되었다. 하지만 저렇게 아예 숫자로 넘겨주면 받는 쪽에서 다시 또 날짜 형식으로 해석해줘야 한다는 문제가 있었다. 화면에 출력을 안 할 거라면 몰라도…
- 그러고 있는 차에 준호님으로부터 다 완성하셨다고 디엠 도착 → 중단.
쓰이지 않은 가지2: 다른 방식도 찾아보았다. 여러번 GET 하지 않고 정렬하는 방법 중 방금 게 1번이라면 2번은 그냥 div 댓글 카드들을 싹 지우고 거꾸로 써붙이는 것이다.
- “div redraw in reverse order” 검색어로 찾은 스택오버플로우:
$.fn.reverseChildren = function() { return this.each(function(){ var $this = $(this); $this.children().each(function(){ $this.prepend(this) }); }); }; $('#con').reverseChildren();
이걸 이용할 수도 있는데 일단 후퇴함.
준호님: 자바스크립트 쪽에서 시간 데이터가 태어나서(?), 어려움 없이 두 시간 데이터를 크기 비교하여 정렬하기를 할 수 있었다.
- “과거순”
- “최신순”
버튼 둘을 누를 때 GET 없이 정렬이 된다.
- 그렇게 준호님의 로직으로 일단 마무리가 되었다.
감상
: 중간에 의사결정해야 하는 분기가 여러 번 있었고, 처음에 작지만 어디서 출발하느냐에 따라 접근 방식과 난이도가 완전히 달라지는 것을 경험했다. 시간 데이터를 프론트 쪽에서 생성해서 POST로 넘겨주는 방식으로 생각하니 훨씬 더 쉬웠던 것처럼.
- 여러 DB에서 댓글을 불러온다고 하더라도 작성된 시간 순서대로 (섞여서) 화면에 출력되게 만들었다.
2. 다섯 명의 mongoDB 연결하기(?)
그런데 어떻게 하나의 app.py에서 다섯 명의 mongoDB데이터에 접속하지? 아이디와 비밀번호를 공개한 접속 링크를 적어주는 것 외에는 방법이 없는 것 같은데… 그리고 ‘내’ 서버가 돌아가고 있지 않은데 어떻게 내 개인 페이지에서 댓글을 ‘받지’?
⇒ 이것도 메인 페이지 댓글 불러오기 기능을 준호님과 하면서 한꺼번에 (거의) 해결했다. 결론부터 말하면 app.py의 POST와 GET 함수 주소는 모든 개인 페이지에서 공유하면 되고, DB는 각자의 mongoClient 객체를 하나씩 만들어서 POST나 GET 함수 안에 써주면 될 것 같다.
⇒ POST에서 받을래도 ‘만약 여기 주소에서 들어온 요청이면 여기 mongoClient로 보내라’같이 분기해야 할 텐데, ‘만약 여기 주소에서 들어온 거면’을 어떻게 추적하지?
다섯 명 합칠 때 할 일
- db는 창민님 것 하나 남겨두기
- app.py에 GET 주소: /api/load_comment POST 주소: /api/save_comment
- 그리고 각각 개인 페이지마다 GET 지우고 POST만 주소 /api/save_comment 남겨두기
- 메인 페이지에 GET 구현하고 주소 /api/load_comment
- 버튼 내거에서 붙이기
- 댓글 버튼에 달린 함수도 내 거에서 붙이기
- index.html에서 <script>태그 안에, 제일 처음 렝더링 완료되면 ‘댓글 한 번 불러와라’ 이걸 살려두면 포스트를 할 때마다 페이지가 새로고침되면서 알아서 새 댓글까지 보여줄 것이고 ‘댓글 보기’ 버튼은 ‘댓글 새로고침’ 버튼이 되어야 할 것이다. 아니면 ‘댓글 보기’버튼에는 아예 GET으로 불러오는 기능을 없애버려도 되겠다. 뭔가 변경이 생긴다면 알아서 페이지가 새로고침 되면서 댓글이 쫙 보일 테니까.
CSS 배운 것
: 일단 느낀 것은 뭐라도 하나 확실하게 (div 포장지까지 포함해서) 바로 그려낼 수 있도록, 익숙한 지대를 만들어 놔야겠다는 것이었다. 지금 좀 익숙하게 느끼는 거로는 버튼들. 버튼은 한 줄짜리로 완성되고 하나의 div로만 포장하면 된다.
HTML 배운 것
: gif 파일이 img태그에 들어가진다는 것.
img 태그의 src=””속성에 파일의 내 컴퓨터 절대 경로값은 먹히지 않는다. http로 시작하는 인터넷 주소를 넣던가 현재 html이 위치한 경로에서 “../static/swimming.png”같이 지정해주어야 했다.
JavaScript 배운 것
: 대체 왜!!! 일반 함수들이 작동을 안 하는지 모르겠다. 이벤트 작동하게 하기에 대해 더 공부해봐야 하나… 아니 다른 블로그들 보면 잘만 작동되던데 나느 ㄴ왜..? 어쨌든 인라인 방식으로 이벤트 함수를 넣어야 작동됐다. 뭐가 문젠지 검색 중.
Python 배운 것
:
에러와 해결 :
4. 파이참에서 깃 push시 remote: Support for password authentication was removed 에러 ✔️
4. 파이참에서 깃 push시 remote: Support for password authentication was removed 에러 ✔️
PS C:\Users\USER\Desktop\Sparta\01_Mini_Project> git push origin master
remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/devocean-han/sparta_projects_01_Mini_Project.git/'
파이참 터미널에서 git push origin master로 푸시했는데 저런 오류 뜸. 깃헙엔 분명 토큰으로 로그인 한 상태였다.
해결 1. GUI로 푸시하니 잘 됨. 왜지??!
해결 2. 깃헙에 비밀번호가 아니라 토큰으로 연결하는 방식을 사용해야 한다는 알람이라고 한다. 근데 난 애초에 토큰으로 파이참에 연결했단 말이지? 그래서 옵션 > git 관리 에 들어가서 지금 연결된 계정을 지우고, 깃헙에서도 새 토큰으로 갱신해서 그걸로 연결하니 마침내 잘 됐다. 아마 깃헙에서 받은 토큰에 문제가 있었던 것 같다. 새 토큰으로 갱신하고 보니 (분명 몇 시간 전에 새로 생성한) 이 전 토큰의 유효기간이 내가 설정한 것과 다르게 이상하게 되어있었던 듯 했다. …아무튼 뭔가가 이상했다.
- 근데 애초에 토큰에 문제 있어서 깃헙과 연결하는 게 안됐던 거라면 GUI 버튼으로 푸시하는 건 왜 된건지? 터미널에서 받는 명령과 파이참이 GUI 버튼으로 보내는 명령이 아예 깃헙 로그인부터 완전히 다른 체계를 사용하는 게 아닌 이상에야…. 아니면 터미널 명령어는 보안이 취약하고 파이참은 자체적으로 보안을 걸어서 보내기 때문에 안전해서 통과됐다든지…
…덕분에 파이참 버튼으로 push도 해봤고 옵션에서 깃 & 깃허브 관리도 이것저것 만져봤다.
다음엔 한 프로젝트에 여러 깃헙 계정을 연결해서 원하는 곳에 push가 가능한지 실험해보고 싶다. 일단 여러 깃헙 계정을 연결하는 것 까진 쉽게 됐는데. push 실험을 못해봤다. 방금 설명한 이 에러가 터져가지고.
개인적으로 어려웠던 점. 아쉬웠던 점
: 해보고 싶은 것 -
- 나의 고난의 길(?)로 끝까지 한 번 가서 구현을 완ㅅ어해보고 싶다. 서버 쪽에서 타임스탬프를 찍어주는 방식으로 어떻게 끝까지 갈 수 잇을까?
- 마지막에 시간순 정렬 로직에 문제가 있다는 것으 ㄹ알았다. 나도 준호님도 달라붙어서 했는데, 나는 그냥 문자열로 된 타임 스탬프를 이리저리 요리해서 숫자로 바꾸는 방식으로 구현해보려 했지만 ‘오후 12:11:24’의 강력한 적을 촉박한 시간에 만나버려서 마주싸우지 못하고 끝나버렸다. 이것도 내 방식으로 끝까지 또 간 것을 보고 싶다.
- css 버튼 정렬도 다같이 개선해보려고 했는데 이건 내가 못 해결했지만 더 이상 붙잡고 싶은 마음이 없다. 시간이 아주 남아돌지 않는 이상…
- 그리고 마지막으로 CRUD 기능 중 UD 기능을 완성해보고 싶다. 인사이트는 얻엇는데…
- 그리고 깃허브에 깃 푸쉬 풀, 머지 연습. 깃 명령어 연습.
Uploaded by N2T