<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yohan-record.log</title>
        <link>https://velog.io/</link>
        <description>🐱‍🏍 Front End Developer</description>
        <lastBuildDate>Wed, 21 Sep 2022 12:20:59 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yohan-record.log</title>
            <url>https://velog.velcdn.com/images/yohan-record/profile/7dcf8782-2f02-44e8-bded-04c5a4353490/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. yohan-record.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/yohan-record" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 25편 - 배포(heroku)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-25%ED%8E%B8-%EB%B0%B0%ED%8F%ACheroku</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-25%ED%8E%B8-%EB%B0%B0%ED%8F%ACheroku</guid>
            <pubDate>Wed, 21 Sep 2022 12:20:59 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-배포">1. 배포</h2>
<p>✍ heroku cloud service 를 이용하여 로컬환경에서만 확인하던 사이트를 url 생성 후 배포시켜 어느 환경에서든 확인할 수 있게 세팅하려고 한다.</p>
<p>heroku 는 서버를 가지고 있는것 처럼 웹의 공간을 대행해주는 cloud platform 이라고 생각하면 될 것 같다. 작업 방식은 git 을 통해 push / pull 을 하며, 소스를 서버에 반영할 수 가 있다.</p>
<p>해당 과정을 진행하며 heroku 회원가입 등 기초 작업들은 따로 포스팅 하지 않고, 실질적인 terminal 창에서 url 생성 및 git 배포 과정만 남겨보겠다.</p>
<blockquote>
<ol>
<li><a href="https://devcenter.heroku.com/articles/heroku-cli">heroku cli download</a>
<img src="https://velog.velcdn.com/images/yohan-record/post/90a0ce13-7f8e-4f5e-b7c0-e85c47258e20/image.png" alt=""> = mac version에서는 terminal 창에서 direct로 입력하여 download를 진행하면 되고, windows 환경에서는 installer로 download가 가능하다.</li>
</ol>
<hr>
<ol start="2">
<li>Procfile 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/b225bef4-6df0-40c0-8daa-3f67684cda0b/image.png" alt=""> = 일종의 설정 .ini file이다. 배포 시 필요한 코드인 것 같다.</li>
</ol>
<hr>
<ol start="3">
<li>heroku login <strong>(이하 단계는 terminal 이용)</strong>
<img src="https://velog.velcdn.com/images/yohan-record/post/ad4979b3-f2b5-4fe9-9668-517d03378978/image.png" alt=""> = 배포를 진행하기에 앞서서, <strong>heroku login</strong> 명령어를 입력 시 로그인 page로 이동하고, 본인의 계정을 입력 후 로그인을 진행하면 다음 단계로 넘어간다.</li>
</ol>
<hr>
<ol start="4">
<li>app 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/e1fd38c7-e7b7-4b7a-b040-0602ceccbbff/image.png" alt=""> = 접속할 주소를 제공해주는 app을 생성한다. heroku create 명령어 뒤에는 생성하고자 하는 name 을 대입시키면, https 로 시작하는 url이 생성된다.
그 후, 주소값 대입 시 접속은 되나, 별다른 내용이 없을 것이다. 보여주고자 하는 내용을 <strong>배포</strong> 시켜야 보이게 된다.</li>
</ol>
<hr>
<ol start="5">
<li>local -&gt; heroku로 file 전달 (add)
<img src="https://velog.velcdn.com/images/yohan-record/post/f3b4e0b9-0fe1-4642-bd19-64b58efb87f4/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/3e1b4a28-36af-40d5-bbc3-86e50c1669f8/image.png" alt=""> = 서버에 올릴 file 목록들을 add 시킨다.</li>
</ol>
<hr>
<ol start="6">
<li>commit
<img src="https://velog.velcdn.com/images/yohan-record/post/16a36c35-4d8c-48d4-8da7-53b1a060bd73/image.png" alt=""> = 배포 시킬 file들을 add 시킨 후, 서버에 commit 시켜준다. (commit 뒤의 내용들은 commit message를 뜻한다.)</li>
</ol>
<hr>
<ol start="7">
<li>push 
<img src="https://velog.velcdn.com/images/yohan-record/post/45ee0045-64d2-43d8-9afd-81013fef853f/image.png" alt=""> = commit 된 file들을 push 시켜서 실질적으로 서버에 반영시킨다.
하지만, 하단에 repository error 가 보인다. <a href="https://stackoverflow.com/questions/18406721/heroku-does-not-appear-to-be-a-git-repository">원인은, remote 주소가 변경되지 않아 발생한 error</a> 였다.</li>
</ol>
</blockquote>
<p>이같은 경우에는 생성된 app name을 연결시켜주면 된다. 😎<img src="https://velog.velcdn.com/images/yohan-record/post/ece897a2-467b-4c5f-8907-192feb9047d8/image.png" alt=""> = *<em>즉, heroku git remote -a를 나의 app으로 변경시켜 달라는 의미이다. *</em>정상적으로 remote 된 것을 확인할 수 있다.</p>
<blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/f4b2aa37-42f0-452d-9519-bccfde0dfe5c/image.png" alt=""> = 정상적으로 변경 후, push를 진행할 시,</p>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/dcfda429-4788-4915-811b-603bd6cb44e1/image.png" alt=""> = done ! 배포가 완료되고 flask 실행까지 진행된다.</p>
<hr>
<ol start="9">
<li>배포 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/9442eee1-1bf8-4e4f-ba40-cab0b991ef34/image.png" alt=""> = 로컬에서 작업한 화면을 생성한 app url을 입력 후 페이지 확인 시, 정상적으로 배포 된 것을 확인할 수 있다!</li>
</ol>
<hr>
<ol start="10">
<li>heroku 30 minute
현재 간단한 onlinestore 테스트를 위해, heroku 라는 cloud platform 을 이용하여 배포하였는데, heroku의 특징이 30분 내에 접속하지 않을 시 잠자기 모드로 변환된다고 하였다.</li>
</ol>
</blockquote>
<p>  사실, 테스트가 아닌 실제로 onlinestore를 운영할 때는 정식적으로 값을 지불하고 서버를 구축하여 사용 할 것인데, 테스트용으로 확인하기 위해서는 heroku cloud 가 필요했다.</p>
<blockquote>
</blockquote>
<p>  그래서 알아본 결과, <a href="https://nhj12311.tistory.com/283">자신의 도메인을 setInterval을 활용하여 호출시켜주는 방법</a>도 있었고, <a href="http://kaffeine.herokuapp.com/">url만 입력하면, 스스로 호출을 해주는 솔루션을 가진 홈페이지</a>도 존재하였다.</p>
<blockquote>
</blockquote>
<p>  일단 등록을 시켜 둔 상태고, 이렇게 결과물이 완료되었다.</p>
<p>  앞으로의 계획은 수많은 것들이 구상되어 있는데, 사업 아이템으로 점차 확장시킬 항목들이라 추후에 버전업이 되고 상용화 될 때 포스팅하겠다.</p>
<p>  구상한 계획들을 준비하는 아주 큰 첫걸음이 된 작업물이었다고 생각한다!! 😎😎</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 24편 - 구매 목록 마무리]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-24%ED%8E%B8-%EA%B5%AC%EB%A7%A4-%EB%AA%A9%EB%A1%9D-%EB%A7%88%EB%AC%B4%EB%A6%AC</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-24%ED%8E%B8-%EA%B5%AC%EB%A7%A4-%EB%AA%A9%EB%A1%9D-%EB%A7%88%EB%AC%B4%EB%A6%AC</guid>
            <pubDate>Wed, 21 Sep 2022 11:42:20 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-구매한-주문-목록">1. 구매한 주문 목록</h2>
<p>✍ 결제를 성공할 시, 각 상품의 status 값이 &quot;complete&quot; 값으로 변환된다. 하지만, 현재 주문 목록에는 주문을 실패한 항목들까지 노출이 되고 있다. 즉, status가 complete(주문완료) 된 항목만 뿌려지게 해보겠다.</p>
<blockquote>
<ol>
<li>주문 목록 로직 이해
<img src="https://velog.velcdn.com/images/yohan-record/post/9f443ffa-3ecd-4093-854b-2fd4ecc3f257/image.png" alt=""> = find가 정의된 부분을 찾아가보면(models &gt; order.py) 주문목록의 document 모두를 가져오게 처리되어 있다.
<img src="https://velog.velcdn.com/images/yohan-record/post/5d4baa47-b857-4583-928b-63858ae9831d/image.png" alt=""> 그러므로, 현재 수정할 방법은 status값이 complete 된 항목들만 가져올 것이다.</li>
</ol>
<hr>
<ol start="2">
<li>상태값 생성 (controllers &gt; order.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/25776fb6-2630-4430-9d7f-04f153378d9f/image.png" alt="">= status가 complete인 항목을 match 변수에 대입시키고, document 전체에서 가져왔던 주문목록을 match값만 가져올 수 있도록 find 내부에 대입시켜준다.</li>
</ol>
<hr>
<ol start="3">
<li>받아올 값 생성 (models &gt; order.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/0c3defdc-17bc-4599-82b6-10a3cf19d678/image.png" alt=""> = match 가 없는 경우에는 {} 내부 값을 사용한다고 정의 시켜주고, match 값을 대입시켜준다.
match 값은 status 가 complete값이므로 주문이 성공한 목록만 그대로 가져올 것이다.</li>
</ol>
<hr>
<ol start="4">
<li>결과화면
<img src="https://velog.velcdn.com/images/yohan-record/post/40f730c1-ed00-4018-b579-d083b49e43b5/image.png" alt=""> = 상태값이 complete인 주문 목록들만 뿌려지게 된다. (테스트를 조금 진행해서 해당 항목들이 구분이 잘 가지 않겠지만 .. ^^;; db를 통해서 확인해보면 complete 값이 맞다.)</li>
</ol>
</blockquote>
<p>이렇게 주문 파트가 마무리 되었다 ! 🎉</p>
<p>이제 남은 부분은 현재 로컬에서 작업한 파일들을 주소값을 입력 했을 때, 어느 환경에서나 확인할 수 있도록 하려고 한다.</p>
<p>다음 시간에는 배포로 마무리 해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 23편 - 상품 결제(4)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-23%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C4</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-23%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C4</guid>
            <pubDate>Sat, 03 Sep 2022 03:17:03 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-payment-complete-성공">1. payment complete 성공</h2>
<p>✍ payment 결제가 완료된다면, 완료된 정보를 ajax 내부 done data에 전달하는 작업을 해 보겠다.</p>
<p>이번 작업을 하면서 구문에 익숙하지가 않다보니, 정말 별것도 아닌 디버깅 문제로 새벽까지 재미나게(?) 해결해본 이번 챕터이다 😵‍💫</p>
<p>확실히 겪은 문제를 토대로 작업내용을 공유해 보고자 한다.</p>
<p>우선, controllers &gt; payment file에서 성공하게 되면 order id와 message를 전달해 주게 된다.</p>
<p>그 전달받은 값을 ajax done 값에 활용할 것이다.</p>
<blockquote>
<ol>
<li>가맹점 서버 결제 API 성공시 로직
<img src="https://velog.velcdn.com/images/yohan-record/post/7474d950-33f1-4932-8f73-983c45ad6569/image.png" alt=""> = 성공 시 message를 success로 전달했으므로 ( <strong>return jsonify({&#39;order_id&#39;: merchant_uid, &#39;message&#39;: &#39;success&#39;}</strong> = 전달을 받기 위해 jsonify 구문 사용 ) 
), data의 message가 success일 경우 구문을 하나 생성한다.</li>
</ol>
<hr>
<p> <img src="https://velog.velcdn.com/images/yohan-record/post/aa7cfa7f-adca-4621-9dee-5ae7f137829c/image.png" alt=""> = 성공한다면, data에서 전달받은 id를 정의하고, success 주소값을 생성하여 해당 url로 요청한다는 구문이다.</p>
</blockquote>
<p>🧨🧨여기서 주소값을 넘길 때 <strong>&#39;</strong> 가 아닌, <strong>`</strong> 로 넘겨주어야 한다. 이 백틱을 잡아내기위해 정상적인 코드를 몇번이나 엎었다 😂😂 
하지만 확실히 알고 두번다시 실수하지 않을 것 같아 뜻깊은 경험이었다고 생각한다 😎 🧨🧨</p>
<blockquote>
<hr>
<ol start="2">
<li>결제 실패 시 로직
<img src="https://velog.velcdn.com/images/yohan-record/post/ab651598-84a4-493e-9543-05e1620bf5b4/image.png" alt=""> = 단순하다. alert 창을 띄우고 상품 list(main) page로 이동 시켜주면 된다. 하지만, data alert를 사용하기 위해서는 몇가지 세팅이 필요하다.
<img src="https://velog.velcdn.com/images/yohan-record/post/83d5583a-2770-4a84-8369-94b75b7ef121/image.png" alt=""> = (controllers &gt; payment.py) message로 전달을 하고, alert창에서 data의 message로 받아준다면 해당 내용이 정상적으로 보여 질 것이다.</li>
</ol>
<hr>
<ol start="3">
<li>SUCCESS API 생성 ( controllers &gt; payment.py )
<img src="https://velog.velcdn.com/images/yohan-record/post/bfe14377-0047-4d3d-9765-2e0f4eac13f3/image.png" alt=""> = ajax 내부에서도 order_id값을 parameter로 받아왔기 때문에 해당 구문에서도 order_id를 요청해 받아오고, 그 요청한 고유 id값을 넘겨주었다.</li>
</ol>
<hr>
<ol start="4">
<li>payment_complete.html 내부에서 값 출력
<img src="https://velog.velcdn.com/images/yohan-record/post/9aac9ef8-6901-437d-8663-561d0bbee831/image.png" alt=""> = 해당 주문 내역을 상세하게 확인하기 위해 주문 완료 메시지 및 order_id값만 넘겨주었다.</li>
</ol>
<hr>
<ol start="5">
<li>주문 및 결제 테스트
= 하지만 결제 시 &quot;비정상적인 결제입니다.&quot; 라는 alert가 출력 될 것이다. 실패되어 fail 구문으로 튕겼다는 뜻이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/3eede8ae-b296-4f63-86d1-3318dea6789f/image.png" alt=""> = 데이터가 없거나 amount와 상품 가격이 일치하지 않은 경우에 else 구문이 작동되었을 것이다.</li>
</ol>
<hr>
<p>이유는 product의 price는 string값으로 존재하는데, payment_data의 amount는 int로 되어있다. type이 달라서 같지 않은 부분이 생긴 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/457c0f9c-ba90-45f0-82d5-f901fa5f2c35/image.png" alt=""></p>
<hr>
<p>방법은, product를 저장할 때 int값으로 변경해주고 <img src="https://velog.velcdn.com/images/yohan-record/post/5cf7bf14-dcad-4375-81f7-a3643f72a08a/image.png" alt=""></p>
<hr>
<p>update 를 해줄때도 price값을 int값으로 변경 시켜준다. <img src="https://velog.velcdn.com/images/yohan-record/post/40d23668-5bc8-4434-a3e8-deebb0deaf3e/image.png" alt=""></p>
<hr>
<p>이제 별다른 변수가 없다면, 주문 및 결제가 정상적으로 완료 될 것이다.
테스트를 통해 확인 해 보겠다.
<img src="https://velog.velcdn.com/images/yohan-record/post/834af4cf-cefe-45f3-93a1-a8f3e3bebc87/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/e07792d0-294f-4c90-88d8-5347e2bc6722/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/a9445a4e-15cc-484e-b434-64e26ce6e669/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/356becc7-a2e4-4441-b956-f1131f9d9fe5/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/8ae802af-d219-41c4-b579-9fbb09f0b2fe/image.png" alt=""> = 상품정보, 주문정보, 결제정보 등이 db에 담긴 내역이며, 실제 주문 후 결제까지 거쳐 금액이 빠져나가는 것도 정상적으로 작동되는 것을 확인하였다!</p>
</blockquote>
<p>이렇게 주문 후 결제까지 구현을 해 보았다.</p>
<p>온라인 스토어 작업을 하던 중 개강시기가 겹쳐 끝까지 만들 수 있을까 걱정했는데, 수업 중간마다 여유시간이 생겨 차질없이 마무리 할 수 있을 것 같다 😎 </p>
<p>다음시간에는 구매 목록을 마무리 해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 22편 - 상품 결제(3)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-22%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C3</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-22%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C3</guid>
            <pubDate>Wed, 24 Aug 2022 12:30:39 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-결제-성공-시-flask-처리-api">1. 결제 성공 시 flask 처리 API</h2>
<p>✍ 결제가 완료된다면, 완료의 단면적인 부분이 아닌 여러 절차를 생각해 보아야 한다. 우선, 간단한 로직을 생각해보면
<strong>(1)</strong> 결제가 완료되고
<strong>(2)</strong> 결제가 실제로 정상적으로 완료되었는지 확인하는 절차가 필요하며
<strong>(3)</strong> 결제에 대한 정보를 저장하고
<strong>(4)</strong> 주문 document status를 완료 상태로 업데이트 시키는 API가 필요하다.</p>
<p>각 순서별로 코드를 짜서 API를 추가시켜 보겠다.</p>
<blockquote>
<ol>
<li>route 및 함수 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/d602ee80-734a-4c4e-9704-eb1226c2ed44/image.png" alt=""> = complete 주소로     받고, 함수를 생성했으며 결제 성공 또한 로그인이 되어있다는 전제 하에 진행되므로 로그인 여부를 체크하는 코드를 추가시켰다.</li>
</ol>
<hr>
<ol start="2">
<li>request data 및 결제관련 id값 받아오기
<img src="https://velog.velcdn.com/images/yohan-record/post/5643e244-ab34-4802-85bb-63e838e827b5/image.png" alt=""> = request_data의 경우에는 <strong>payment.html file</strong> 내부의 ajax값 안의 data를 뜻하고, 그 data 안에는 <strong>imp_uid</strong>및 <strong>merchant_uid</strong>의(결제에 필요한 data값들)을 담아둔 것이다. 이 값들을 받아와서 저장해야 하므로 가져온다.</li>
</ol>
</blockquote>
<p>🔖 <strong>payment.html 참고</strong><img src="https://velog.velcdn.com/images/yohan-record/post/c237de2d-ccd6-473e-b39d-57762831fae0/image.png" alt=""></p>
<blockquote>
<hr>
<ol start="3">
<li>결제가 정상적으로 완료되었는지 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/83ba1482-e01d-4dce-94b1-3d95edeb6a60/image.png" alt=""> = 확인을 위해서는 iamport API를 이용해서 확인해야 하는데, <a href="https://docs.iamport.kr/implementation/payment#server-side-logic">API site</a>에서는 node를 활용하여 작업을 해두었다.😵‍💫
그러므로, node 코드를 확인하여 python code 로 알맞게 작업을 해 보겠다.</li>
</ol>
</blockquote>
<p>(1) 우선, API 상의 url을 사용한다.
(2) data key(iamport 관리자 홈페이지 참조)<img src="https://velog.velcdn.com/images/yohan-record/post/0375ce27-78ff-4a08-bc3b-54f6c1a45fb8/image.png" alt="">
(3) headers 정의 <strong>headers = {&#39;Content-Type&#39;: &#39;application/json&#39;}</strong> 
= application/json type으로 보내겠다고 선언</p>
<blockquote>
</blockquote>
<p>(4) 요청 보내기<img src="https://velog.velcdn.com/images/yohan-record/post/a5a76610-a45b-498b-b099-8f79e6c40ffa/image.png" alt=""> = 너무 정신이 없다. 하지만 이해를 위해서는 어쩔 수 없었다(?)
값을 변수에 담고, 그 변수가 어디에 저장되고 어디에 뿌려지는지 정확히 이해하고 넘어가야 혼동을 줄일 수 있다.</p>
<blockquote>
</blockquote>
<p>우선 url, headers, data 값을 res 변수에 담았다.
<img src="https://velog.velcdn.com/images/yohan-record/post/22e3e572-02d4-4657-b4b1-54d0644d77d7/image.png" alt="">** = request 및 json이 import 되어 있지 않으므로, 사용을 위해서 import 시켜준다.**</p>
<blockquote>
</blockquote>
<p><strong>res = res.json()</strong>
그 후, response를 json으로 변환하여 다시 res 변수에 담아준다.
<img src="https://velog.velcdn.com/images/yohan-record/post/c09975c2-352c-4130-9110-2cf0cfbb56e9/image.png" alt=""> = API를 살펴보면, data를 감싼 getToken을 data.response의 access token 으로 받아오는 것을 확인할 수 있다.
이 코드를 동일하게 작업하되, python으로 변경하면
<img src="https://velog.velcdn.com/images/yohan-record/post/d08305c9-70d3-4019-b1f6-4125696db7c5/image.png" alt=""> = response로 접근하여 access_token을 가져온다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/817912ca-b6bd-434e-a914-c7415259a0ba/image.png" alt=""> = 결제정보를 조회할 수 있는 API를 사용하기 위해서 token을 발급받았고, 그 발급받은 token을 이용하여 조회할 수 있게끔 작업해 준 코드이다.</p>
<blockquote>
</blockquote>
<p>물론 API 상에서 해당 코드가 node로 작업되어 있고, python 형식에 맞게 변환시켜 주었다.</p>
<blockquote>
</blockquote>
<p>🔖 참고)<img src="https://velog.velcdn.com/images/yohan-record/post/be18b896-2657-4eff-a5cd-7b5690699898/image.png" alt=""></p>
<blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/766c5087-7384-4414-bb41-4525e4c2af69/image.png" alt="">= 그 후, request를 get방식으로 실행하여 json으로 불러온다. ( url 및 headers)
가져온 후 response key값으로 payment_data를 꺼내온다.</p>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/666883bd-4c16-4b97-8093-2f0815050b4c/image.png" alt=""> = payment data와 payment_data 내부의 실제 결제한 값(amount) 와 상품가격(product &gt; price) 가 같다면 -&gt; 정상적으로 결제가 완료된 것이다.
(<strong>status 값</strong>은 success로 세팅해준다.)</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/a2769008-575b-4981-b06c-d5aa4ce47a0f/image.png" alt=""> = 그 가격은 <strong>order</strong>에서 찾아준다. order 가 없다면 return 값을 띄워준다.</p>
<blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/c4e95de2-8a4c-45d2-b5eb-07879861718c/image.png" alt=""> = 결제에 대한 정보를 저장하기 위해 insert_one을 이용하여 주문 정보와, 결제정보와, 상태를 저장해 준다.
payment class는 현재 존재하지 않으므로, 생성해 주어야 한다.</p>
<hr>
<p>(5) models &gt; payment.py 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/c6f23e6c-6fd0-42ee-9543-9485041f0c04/image.png" alt=""> = 주문정보, 결제정보, 상태를 받아온다. </p>
<hr>
<p>(6) payment 생성 후 import
<img src="https://velog.velcdn.com/images/yohan-record/post/bf75ea40-1433-4f11-ba81-035050f14266/image.png" alt=""></p>
<hr>
<p>(7) 비 정상적인 결제일 경우
<img src="https://velog.velcdn.com/images/yohan-record/post/33b28bd9-ec84-446c-98e1-f2fc6cffff18/image.png" alt=""> = 이렇게 결제에 대한 정보를 저장하는 단계를 거친 후, 주문 document status 상태로 update 시켜주어야 한다.</p>
<hr>
<p>(8) 주문 document status 상태로 update
<img src="https://velog.velcdn.com/images/yohan-record/post/7ca59e80-4d9f-4241-8c77-8d43d1f755df/image.png" alt=""> = status 값은 complete로 지정해주고, status 값과 merchant_uid 값을 update 시켜준다. 
다 완료가 되었다면, order_id는 merchant_uid 값으로, message는 success 값으로 return 시킨다.</p>
<hr>
<p>(9) order update_one ( models &gt; order.py )
<img src="https://velog.velcdn.com/images/yohan-record/post/cc542c95-be69-47e7-bc2b-bd4f159c941f/image.png" alt=""> = 어떤 주문정보를 update 할 것인지 확인</p>
</blockquote>
<p><strong>payment.html ajax 내부</strong>에서 결제가 성공될 경우 요청 시 생성한 API로 들어와서 결제 확인 및 결제 정보를 저장하고 주문상태를 update 해주게끔 코드를 작성했다 🎉</p>
<p>기존 API를 활용하여 python 형식에 맞게 작업하다보니 시간도 배로 걸리고 구문이 아직 익숙치 않다.</p>
<p>이번 작업이 마무리되면, 여러 type의 쇼핑몰도 생성하고 간단하지만 다른 조건부들을 주어 선택지를 다양하게 생성해 보려는 계획을 가지고 있다!</p>
<p>다음 시간에는 API가 성공이 되면 정보를 ajax 내부 done data에 전달하는 작업을 해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 21편 - 상품 결제(2)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-21%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C2</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-21%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C2</guid>
            <pubDate>Mon, 22 Aug 2022 14:26:26 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-결제-요청">1. 결제 요청</h2>
<p>✍ 지난 시간에는 form을 작성하고, 작성한 form의 고유 id값이 넘어오는 것 까지 확인 해 보았다. </p>
<p> 이번시간에는, iamport를 활용하여 pg사를 연동시켜 실제 금액이 빠져나가고, 취소했을 때 환불처리 되는 것 까지 구현해 보려고 한다.</p>
<p> 기존에 정말 해보고 싶었던 작업이고, 까다로운 요소들도 많지만 차근차근 작업 해 보겠다!</p>
<blockquote>
<ol>
<li><a href="https://docs.iamport.kr/implementation/payment#add-library">iamport script import</a>
<img src="https://velog.velcdn.com/images/yohan-record/post/03d3778a-63be-42b0-9b23-f591a6979f82/image.png" alt=""> = library 사용을 위해서는 지원하고 있는 script file을 import 시킨 후 작업을 시작한다.
{SDK-최신버전} 부분은 현재 최신버전을 문서에서 서칭하여 표기해 주면 된다.
= <strong>iamport.payment-1.1.8.js</strong></li>
</ol>
<hr>
<ol start="2">
<li>결제 준비 코드 작성
<img src="https://velog.velcdn.com/images/yohan-record/post/bcbb3e39-7724-4e09-bc8f-9c72923f3bad/image.png" alt=""> = 가맹점 식별코드는 iamport 관리자콘솔 -&gt; 상점/계정관리 -&gt; 내 식별코드 Appkeys 에서 확인가능하다.
<img src="https://velog.velcdn.com/images/yohan-record/post/e32d631f-678c-47cc-bb74-6e2963a6c02a/image.png" alt=""> = 확인한 식별코드를 Imp.Init 뒤 식별 코드에 붙여넣어준다.</li>
</ol>
<hr>
<ol start="3">
<li>결제 요청 코드 작성
<img src="https://velog.velcdn.com/images/yohan-record/post/cb747d69-e827-4231-a7e7-effde7541057/image.png" alt=""> = 해당 코드를 입력 시 정보가 기입되어 있는 pg사 결제창(이전 작업에서 <strong>다날</strong> 로 테스트pg사를 추가해 둠)이 나타날 것이고, 실질적으로 결제가 가능할 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/7044cede-a574-4146-aea5-831a457b4c12/image.png" alt=""> = 우선 작업 후 결과 코드인데, 하나씩 순차적으로 설명해 보겠다.</li>
</ol>
</blockquote>
<p>DOM이 로드 된 후, requestPay 함수를 호출시켜 정상적으로 pg사 popup을 띄우면 성공이다. <del>그렇게 되야한다...</del></p>
<blockquote>
</blockquote>
<p>예상대로라면 문제없이 PG사 결제창이 popup으로 뜰텐데 <strong>결제 실패시 로직</strong>이 떠버렸다. 즉, reqeustPay 함수가 정상적으로 실행되지 않고, else로 튕겼다는 것이다 😂</p>
<blockquote>
</blockquote>
<p>우선 로직을 따라 차근차근 하나씩 읽어보았다.</p>
<blockquote>
</blockquote>
<p>구문상 문제는 없어보였고, 함수 안의 내용도 하나씩 살펴보았다.
구문을 몇번이고 다시 읽어보고, 서칭을 해보아도 답이 없었는데, 하나 이상한 점이 있었다.</p>
<blockquote>
</blockquote>
<p>나는 pg사를 다날로 세팅했는데, 현재 코드 상으로는 inis가 입력되있다(?)
<img src="https://velog.velcdn.com/images/yohan-record/post/629a8d64-e453-40e0-b617-b3ddca876d0e/image.png" alt=""> = 이 구문을 danal_tpay로 입력하니 결제창이 잘 나온다 하하하 ^___^ </p>
<blockquote>
</blockquote>
<p>별거 아닐거 같단 느낌이 들었고 예상은 했는데 이 문제로 <strong>40분</strong>이나 배움의 시간이 확보되었다 ..😵‍💫😵‍💫</p>
<blockquote>
<hr>
<ol start="4">
<li>실 데이터 추가
<img src="https://velog.velcdn.com/images/yohan-record/post/49198bdc-1882-427b-85ac-967e7fa4f069/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/b1a1aa9d-7d46-4707-ab60-208f0c6cb330/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/6d197781-608c-41a3-bd4d-25519ceb642a/image.png" alt=""> = 실제로 결제가 진행되는 pg 사 결제창이 나타났다.
신한pay로 직접 결제 후 나타나는 화면들을 구현해 보겠다.</li>
</ol>
</blockquote>
<hr>
<ol start="5">
<li>실결제테스트
<img src="https://velog.velcdn.com/images/yohan-record/post/d646a772-e9a7-4810-a666-fbf2badbf518/image.png" alt=""> = 신한pay로 결제 후 정상적으로 결제가 된다면 결제를 기다리는 popup 창이 하나 나타난다. 여기서 결제를 클릭하게 된다면 실제 돈이 빠지게 되며, 정상적으로 구매가 완료된다.<blockquote>
</blockquote>
결제내역 확인 부분에서는 수단, 개월수, 구매자 및 이메일, 상품명, 상품금액, 결제금액 등이 db의 실제 data가 정상적으로 출력되고 있다.
<img src="https://velog.velcdn.com/images/yohan-record/post/3e786d49-f01a-49ab-9984-1b2e858c2703/image.png" alt=""> = 결제 버튼 클릭 시 console에 찍힌 결제 성공 text가 출력된다.
아직 결제 후 이후 과정을 작업하지 않았기에 console 만 뜨는것이 정상이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/04227347-4108-4ac9-8669-382f97e30dea/image.png" alt=""> = 그 후, 상품의 금액이 정상적으로 출금되는 것이 확인된다.<blockquote>
</blockquote>
</li>
</ol>
<hr>
<ol start="6">
<li>결제 승인 내역 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/a0c22d43-6c4e-4666-b10b-c4673d467fb0/image.png" alt=""> = 여러번 테스트를 하였는데, 미결제 내역 및 구매한 내역이 정상적으로 출력된다.<blockquote>
</blockquote>
🔖 만약, 구매가 완료된 상품을 <strong>판매자의 사정</strong>으로 <strong>환불처리</strong>를 하거나, 구매자의 사정으로 구매를 취소 할 수도 있다. 그러므로 현재 관리자 콘솔에서 <strong>상품을 취소</strong>할 시 정상적으로 환불처리가 되는 것도 확인하였다.
<img src="https://velog.velcdn.com/images/yohan-record/post/b9ae4ed9-ac64-408d-a95d-f78e1d699340/image.png" alt=""><blockquote>
</blockquote>
</li>
</ol>
<hr>
<ol start="7">
<li><a href="https://docs.iamport.kr/implementation/payment#send-imp-uid">결제 성공 시 결제정보전달</a>
= 결제 요청이 끝난 후 완료가 되었을 때 flask에 전달해 주어야 한다.
<img src="https://velog.velcdn.com/images/yohan-record/post/48a9a2a1-8933-43fa-b21b-41dcf5d9790f/image.png" alt=""><blockquote>
</blockquote>
= payment/complete 주소 및 post방식으로 전달해 주었다.</li>
</ol>
<p>실질적으로 구매한 금액이 정상적으로 출금되고, 취소한 상품에 대해서 즉시 환불처리 되는 로직을 구현해 보았다!</p>
<p>순탄하게 작업이 진행되면 좋겠지만, 오류가 생기고 그 오류를 해결하는 과정에 있어서 더 많은 것들을 찾게 되고 부가적으로 득이 되는 것들이 더 많은 것 같았다. 😎🎉</p>
<p>다음 시간에는 결제 성공 API를 작성해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 20편 - 상품 결제(1)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-20%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C1</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-20%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B2%B0%EC%A0%9C1</guid>
            <pubDate>Mon, 22 Aug 2022 12:28:18 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-구매-프로세스">1. 구매 프로세스</h2>
<p>✍ 우선, 상품을 구매 후 결제하는 과정에 있어서 해당 로직을 생각나는대로 적어보겠다.</p>
<p>결제 버튼 클릭 시 결제 요청 페이지가 나오고 -&gt; 결제 창이 오픈 되며(통상적으로 popup이 될 것 같다) -&gt; 구매자가 결제를 완료할 시 -&gt; 결제 확인 화면이 나타나고 -&gt; 주문이 완료되며 (결제 금액 및 주소 확인) -&gt; 상품을 구매 완료 시킨다.</p>
<p>결제를 구현하는데에 있어서는 iamport를 사용할 것이며,</p>
<p>iamport -&gt; 결제 요청 시 결제 창을 열어주고,
사용자 -&gt; 결제를 하게 되면 결제 후 결제확인 단계에서도 <strong>iamport API</strong>를 통해 결제가 제대로 된 지 확인 할 것이며,</p>
<p>주문이 완료 되었다면, 주문 상태를 update 시켜주면 정상적으로 결제가 포함된 주문이 완료 될 것이다.</p>
<p>이전 시간에는 주문하기 버튼을 클릭 시 무조건적으로 완료 페이지로 넘겼다면, 이번 시간에는 결제 요청 페이지를 생성 후 고유 id값을 넘겨 받는 것 까지 해보겠다.</p>
<blockquote>
<ol>
<li><a href="https://www.iamport.kr/?gclid=Cj0KCQjw0oyYBhDGARIsAMZEuMvlVxcNj84QbRcXk2CMKkyAYOSTdFT_m8LtngamWZQLiOqL6Hvm8bIaAgbJEALw_wcB">아임포트 회원가입</a></li>
</ol>
<hr>
<ol start="2">
<li>PG사(다날 이용) 테스트모드 저장
<img src="https://velog.velcdn.com/images/yohan-record/post/50596e9d-bef5-460b-850c-f135f5f0c378/image.png" alt=""></li>
</ol>
<hr>
<ol start="3">
<li>controllers &gt; payment.py 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/33917f0c-1503-4919-b74f-a366472e2278/image.png" alt=""> = 우선, 파일만 생성 한 후 blueprint에서 payment 값으로 등록시켜준다(payment/filename)
<img src="https://velog.velcdn.com/images/yohan-record/post/6fe723ae-214f-41e3-be91-9d4937f30010/image.png" alt=""></li>
</ol>
<hr>
<ol start="4">
<li>결제 요청 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/c78db44c-c176-4aec-822d-181f414cb49c/image.png" alt=""> = payment를 이용하여 /request 값으로 route 시켜 돌려주고, request_payment 함수를 하나 생성한다.
<img src="https://velog.velcdn.com/images/yohan-record/post/65635261-b25a-4372-9a92-707aa7d61295/image.png" alt=""> = 결제 요청을 하기 위해서는 로그인이 당연시 되어야 하는 부분이므로, 로그인을 check 하는 코드를 기존에 사용했던 것과 동일하게 작성해준다.
<img src="https://velog.velcdn.com/images/yohan-record/post/c7208d09-36fe-40fe-ae88-991c58801412/image.png" alt=""> = 어떤 주문에 대한 결제인지에 대해 알고 있어야 하므로, order에 대한 정보가 필요하다. </li>
</ol>
</blockquote>
<p>find_one을 이용하여 order의 id를 가져오는데, 어디서 받아오는지에 대해 명시되어 있어야 한다.</p>
<blockquote>
</blockquote>
<p>그러므로, order_id 변수를 생성 후, .argument.get 으로 값을 받아온다.
즉, 이 값은 request api 로 들어올 때 ? 뒤의 값을 가져오는 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/cab50564-4bdf-4ee1-b78c-6b107b6da52e/image.png" alt="">
받아온 값은 <strong>payment.html</strong> 로 이동시켜준다.</p>
<blockquote>
<hr>
<ol start="5">
<li>app.py -&gt; blueprint 등록
<img src="https://velog.velcdn.com/images/yohan-record/post/97c4a303-a67a-4c72-8f17-bcbe1f2bdc8a/image.png" alt=""></li>
</ol>
<hr>
<ol start="6">
<li>payment.html file 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/a11b87c3-e9e8-403b-aba3-5acd52e6edda/image.png" alt=""> = 현재 넘겨온 값을 확인하기 위해 order 값만 받아온 상태이다. </li>
</ol>
</blockquote>
<p>다른 작업들을 거친 후, 마지막에 주문 폼을 작성한 후 값을 전송한다면, 해당 폼의 내용들이 출력 될 것이다. (마지막에 확인 해 보겠다.)</p>
<blockquote>
<hr>
<ol start="7">
<li>request_payment api를 호출시킬 부분 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/11ffcb6d-99b2-4cbb-9c4f-b9264c43159a/image.png" alt=""> = 주문하기 버튼을 클릭 시 해당 주소값으로 post값이 전송되는데, 값이 전송될 때 request_payment API 가 호출이 되어야 한다.
<img src="https://velog.velcdn.com/images/yohan-record/post/195362e0-bd83-454a-a0a9-d76ae49e645d/image.png" alt=""> = 그러므로, <strong>controllers &gt; product.py</strong> file 에서 redirect 값을 이용하여 호출 시켜 주고, order_id parameter를 이용한다.</li>
</ol>
</blockquote>
<p>🔖 api 뒤 order_id는 insert_one, 즉 새로 생성 시 order_id를 가져와야 하므로, order_id 변수를 생성하여 insert_one 생성 구문을 감싼다.</p>
<blockquote>
<hr>
<ol start="8">
<li>models &gt; order.py file 에서 return 처리
<img src="https://velog.velcdn.com/images/yohan-record/post/1435fe8e-48d6-4eeb-9b31-0b687c37f8d0/image.png" alt=""> = 생성되었을 때, 고유번호를 return 시켜준다.</li>
</ol>
</blockquote>
<p>즉, 새로 생성하는 요소들을 new_order_doc 변수로 감싸고, 그 감싼 값을 return 시켜준 후, product.py에 order_id를 받아서 redirect 시 order_id를 parameter 로 넘겨준다.</p>
<blockquote>
<hr>
<ol start="9">
<li>payment import(controllers &gt; product.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/4555e1ed-d329-411d-9f7f-7ecdc7f7900e/image.png" alt=""></li>
</ol>
<hr>
<ol start="10">
<li>주문 폼 작성 및 넘겨준 값 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/531634e6-f4e0-4679-8116-f3172fe3f1e7/image.png" alt=""> = 값을 담아서, post값으로 전송 시 해당 값들이 출력되어야 한다. (현재 payment.html file에서 order 값 출력되도록 작업 <strong>{{order}}</strong> )</li>
</ol>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/81e7961d-a870-4259-aee9-fc6c7954e8cc/image.png" alt=""> = form 내부에 작성한 값들과 고유 id값이 정상적으로 넘어오는 것을 확인할 수 있다.</p>
<p>작업을 하다 보니, 실제로 사용하기 위해서는 PG사 심사 및 여러까지 까다로운 절차들이 많을 것으로 예상된다 😂 </p>
<p>하지만, 실질적으로 직접 사용할 사업자를 초빙(?) 하여 심사 및 결제시스템을 도입하여 사용해 본다면 점차적으로 type 이 다른 여러 쇼핑몰을 만들어 낼 수 있겠다는 판단이 들었다. (<strong><del>곧 개강이라 시간이 문제다 시간이 ㅠㅠ</del></strong>)</p>
<p>아무쪼록 목표에 점점 가까워지고있다 !!</p>
<p>다음 시간에는 결제요청을 구현해 보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 19편 - 상품 구매결과 조회]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-19%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B5%AC%EB%A7%A4%EA%B2%B0%EA%B3%BC-%EC%A1%B0%ED%9A%8C</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-19%ED%8E%B8-%EC%83%81%ED%92%88-%EA%B5%AC%EB%A7%A4%EA%B2%B0%EA%B3%BC-%EC%A1%B0%ED%9A%8C</guid>
            <pubDate>Thu, 11 Aug 2022 14:27:57 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-구매결과-조회">1. 구매결과 조회</h2>
<p>✍ 사용자가 구매를 완료하였다면, 구매를 완료한 상품의 목록 및 상세페이지가 필요할 것이다.</p>
<p>우선, <strong>주문완료 상품의 목록</strong>부터 확인이 가능하도록 구성해 보겠다.</p>
<blockquote>
<ol>
<li>주문완료 controller 생성</li>
</ol>
</blockquote>
<p>📍 <strong>blueprint 생성</strong><img src="https://velog.velcdn.com/images/yohan-record/post/4dfc12a6-20f8-401e-a68e-cf564f55b251/image.png" alt=""> = order 주소를 가진 blueprint controller 생성</p>
<blockquote>
<hr>
<p>📍 controllers &gt; order.py 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/070d8145-f3a4-4936-aa5b-34d5e71a7574/image.png" alt="">= blueprint order 추가 및 order 사용</p>
<hr>
<p>📍 app.py &gt; order blueprint 등록
<img src="https://velog.velcdn.com/images/yohan-record/post/5502abe0-1a7f-4ff9-9149-0017c0e7d1a9/image.png" alt=""> = order import 및 prefix는 order는 이용</p>
<hr>
<ol start="2">
<li>구매 완료한 상품 목록 API 생성(controllers &gt; order.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/27ef9ae2-05ae-4a1b-a322-f8b774bb9dd8/image.png" alt=""> = 구매완료된 리스트이므로 당연히 로그인 된 상태에서 확인이 가능하므로 check_login을 사용하여 로그인 유무 체크를 먼저 진행한다.</li>
</ol>
</blockquote>
<p>그 후, 주문목록을 가져와야 하는데, find 함수를 사용하여 가져오도록 하겠다</p>
<blockquote>
<hr>
<ol start="3">
<li>find 함수 생성(models &gt; order.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/12a56389-7d60-442f-994c-cce53d2cb2c2/image.png" alt=""> = db의 orders에 있는 모든 document를 가져와서 orders 변수에 저장시켜주고 orders를 return 시켜준다.</li>
</ol>
<hr>
<ol start="4">
<li>orders 사용
<img src="https://velog.velcdn.com/images/yohan-record/post/3c891825-6b67-49cb-96fd-cd926e7d0390/image.png" alt=""> = import 및 models &gt; order.py에서 return 받아온 orders 사용한다.
이 정보를 가지고 html에서 보여주어야 한다.(orders.html 생성 및 orders 정보 html file에 던져줌)</li>
</ol>
<hr>
<ol start="5">
<li>orders.html file 생성(구매한 주문 목록)
<img src="https://velog.velcdn.com/images/yohan-record/post/70a324fa-70d7-4219-a9ad-fe2f966a99c3/image.png" alt="">
= 여기서 유의할 부분은 render_template 생성 후 product가 아닌 orders를 넘겨주었기 때문에,</li>
</ol>
<p><strong>{% for order in orders %}</strong> = 넘겨준 orders 값을 order로 받아서 order의 product를 타고 해당 값을 가져온다.
<img src="https://velog.velcdn.com/images/yohan-record/post/2037fc94-d58d-4ccb-b91f-d20ad0ce0fb4/image.png" alt=""></p>
</blockquote>
<pre><code>order &gt; product &gt; ___</code></pre><blockquote>
<hr>
<p>  <img src="https://velog.velcdn.com/images/yohan-record/post/568ee530-a61a-45f3-bab9-10f0e4fe273c/image.png" alt="">= 주문목록 페이지 결과화면</p>
<hr>
</blockquote>
<p>우선 주문한 상품의 목록 페이지는 끝이났다.
다음으로는 <strong>주문한 상품의 상세페이지</strong>를 확인해보겠다.</p>
<blockquote>
<ol>
<li>상세 페이지 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/3601d5e6-c9aa-4ab9-aa44-3b1c4e27593f/image.png" alt=""> = 주문 목록과 유사하나, 상품 상세 페이지는 어떤 order인지가 필요하므로 order_id 고유값을 가져온다.</li>
</ol>
</blockquote>
<p>상세페이지도 동일하게 로그인이 필요하여 check_login으로 체크했으며, order_id 하나만 찾으면 되므로, find_one으로 order_id를 주소값에서 받아서 넘겨줄 것이다.</p>
<blockquote>
<hr>
<ol start="2">
<li>넘긴 order_id를 find_one으로 찾기(models &gt; order.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/f1953496-ae14-42a8-bc8a-f18b869200fc/image.png" alt=""> = 넘어온 order_id 값을 _id 주소로(db안의 _id를 찾는것) document를 찾는다.
그 후 order를 return 시킨다.</li>
</ol>
</blockquote>
<p>🔖 ObjectId를 받아온 이유는 db안의 id값이 ObjectID값으로 설정되어 있어 맞춰주었다.<img src="https://velog.velcdn.com/images/yohan-record/post/71a88c0c-63f5-44a5-b2b0-c613ecfa8e31/image.png" alt=""></p>
<blockquote>
<hr>
<ol start="3">
<li>order.html file 생성(주문완료 상세 페이지)
<img src="https://velog.velcdn.com/images/yohan-record/post/ca9db937-ba62-422d-8d58-1ab1d24c764b/image.png" alt=""> = 유의할 점은 주문목록과 동일하게 order의 product 안에 가져올 data들이 있다는  점이다.</li>
</ol>
<hr>
<ol start="4">
<li>주문목록 페이지에서 상세페이지 이동 링크
<img src="https://velog.velcdn.com/images/yohan-record/post/4b372366-96b4-49cc-b188-5459015997ab/image.png" alt="">= orders의 order_id 고유값으로 던져준다(이동) -&gt; order controllers 안의 상세 페이지로 이동되는 부분이 작동된다.
<img src="https://velog.velcdn.com/images/yohan-record/post/be797008-80aa-45b2-92be-56fb9d24f4c9/image.png" alt=""></li>
</ol>
<hr>
<ol start="5">
<li>배송지 / 주문자정보 추가
<img src="https://velog.velcdn.com/images/yohan-record/post/427b3f3e-3415-4ef0-9af9-f9352686c3aa/image.png" alt=""> = order 안의 각자 해당되는 data값을 가져온다.
<img src="https://velog.velcdn.com/images/yohan-record/post/12181bbf-5573-45b6-8ce7-bc3323b6697f/image.png" alt=""></li>
</ol>
</blockquote>
<p>이렇게 주문완료된 목록 및 상세페이지를 구현해 보았다.
직접 사용자 및 상품의 data를 넘기고, 그 넘겨진 값을 받아서 db에서 확인 후 직접 뿌려지는 과정까지 구현해 보니 front와는 또 다른 재미가 있는 것 같다. 😎</p>
<p>다음 시간에는 드디어 <strong>결제 모듈</strong>을 연동시켜 보겠다!!!!🎉</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 18편 - 상품구매]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-18%ED%8E%B8-%EC%83%81%ED%92%88%EA%B5%AC%EB%A7%A4</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-18%ED%8E%B8-%EC%83%81%ED%92%88%EA%B5%AC%EB%A7%A4</guid>
            <pubDate>Thu, 11 Aug 2022 13:17:16 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품구매-프로세스">1. 상품구매 프로세스</h2>
<p>✍ 상품 구매에 대한 전반적인 순서를 그려보고 이해한 후 넘어가는 것이 좋을 것 같아 대략적인 순서를 구성해보았다.</p>
<p>우선 <strong>(1)</strong> 상품 상세 페이지 접속 후 -&gt; <strong>(2)</strong>구매하기 버튼을 클릭할 시 -&gt; <strong>(3)</strong>주문자 정보 입력 page가 나오게 되고,</p>
<p><strong>(4)</strong>주문자 정보 입력 후 결제를 클릭 시 -&gt; <strong>(5)</strong>결제창 및 결제완료 페이지가 호출된다.</p>
<p>그 후, <strong>(6)</strong>상품구매완료 페이지가 호출되며 -&gt;** (7)<strong>구매상품목록을 확인할 수 있는 페이지가 호출되고 -&gt; **(8)</strong>구매 결과 페이지가 호출되는 형식이다.</p>
<p><strong>저장하는 알고리즘</strong> 역시 크게 생각해 본다면,
<strong>(1)</strong> 결제 버튼 클릭 시 주문정보가 생성되고 -&gt; <strong>(2)</strong>상품 구매 <strong>완료</strong> 시 주문 정보에서 주문 상태 값을 <strong>update</strong> 시켜준다.</p>
<p><strong>(3)</strong>그 후, 결제 관련 정보 받아서 -&gt; <strong>(4)</strong>저장된 주문 정보로 구매 상품 목록 및 결과 페이지를 호출한다.</p>
<p>돌아가는 로직은 전반적으로 이해하였고, 직접 코드를 짜보면서 깊게 이해해 보도록 하겠다.</p>
<p>🔖 <strong>html 코드 및 bootstrap을 활용한 스타일 작업의 상세한 설명은 표기하지 않겠다.</strong></p>
<h3 id="⌛-주문-페이지-생성">⌛ 주문 페이지 생성</h3>
<blockquote>
<ol>
<li>상세페이지 &gt; 구매하기 버튼 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/3d0e8084-e4ea-4488-861c-4c043744d720/image.png" alt=""> = 해당 구매하고자 하는 상품의 고유id값을 가지고 order 주소(구매 페이지)로 이동</li>
</ol>
<hr>
<ol start="2">
<li>버튼 누릴 시 주문 가능한 페이지 API 생성(controllers &gt; product.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/4ff235ff-740a-4306-a45f-c3b251bfae08/image.png" alt="">
값을 가지고 render_template 주소를 order_form.html page로 이동시킨다. (주문 페이지에는 상품 정보가 필요하므로 product 넘겨줌)</li>
</ol>
<hr>
<ol start="3">
<li>order_form.html 생성 및 구조작성
<img src="https://velog.velcdn.com/images/yohan-record/post/17c5e1c9-4665-43f6-823b-db0347621c8d/image.png" alt="">= html 코드 구조 및 bootstrap class를 이용하여 간단하게 폼을 생성한다.</li>
</ol>
</blockquote>
<p>  📍 주의할 점은, <strong>각 input에는 고유 id값 및 name값</strong>을 이용해 값을 전송시켜야 한다.<img src="https://velog.velcdn.com/images/yohan-record/post/3309c08b-73df-49f8-9f75-aa827573e649/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>여기서, 우편번호 찾기를 클릭 시 주소를 입력하는 API을<a href="https://postcode.map.daum.net/guide"> 다음에서 제공</a>해준다.</p>
<blockquote>
</blockquote>
<p><strong>다음 API 예제코드</strong>를 복사하여(사용자가 선택한 값 이용하기 -&gt; 예제 코드보기), onlinestore 주문 폼에 맞춰 input값 및 button을 그대로 사용하면 된다. (script는 건드릴 것이 없다.)</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/588903cb-b538-4996-aefc-d18c2191e25e/image.png" alt=""></p>
<h3 id="⌛-주문-api-생성-및-구현">⌛ 주문 API 생성 및 구현</h3>
<blockquote>
<ol>
<li>주문 생성 api
<img src="https://velog.velcdn.com/images/yohan-record/post/1c4ccd03-138d-4333-83ab-966ba31bf656/image.png" alt="">= product정보가 필요하므로 product_id를 받은 후/order 및 post 방식 이용</li>
</ol>
</blockquote>
<p>  order 함수형 선언 및 product_id를 주소에서 받아온다.</p>
<blockquote>
</blockquote>
<p>  그 후 product에 대한 정보를 product_id를 가지고 찾아올 것이므로, 주문정보를 저장할 때 상품에 대한 정보 역시 저장한다.(어떤 상품을 구매한지 확인해야함)</p>
<blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/a958efa2-4881-443c-abb4-65bb821f45db/image.png" alt="">= input으로 들어오는 배송지 정보와 주문자 정보를 받아올 때 사용</p>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/9b663c14-923a-479e-8869-32d42670f34b/image.png" alt=""> = order collection에 insert_one이라는 함수로 product와 form_data, user에 대한 정보를 저장할 것이다. (<strong>order.py file을 models 에 생성하여 사용할 것이다. 우선 Order 사용</strong>)</p>
</blockquote>
<p>이 user는 check_login을 할 때 사용한 것이므로(로그아웃에서 사용) 그대로 가져온다.
<img src="https://velog.velcdn.com/images/yohan-record/post/ee7b3072-83b0-4262-8687-7d2e3939df32/image.png" alt=""> = 만약 로그인이 되어있다면 user정보를 가지고 사용할 것이고, 로그인이 되어있지 않다면 return 값으로 돌려보낼 것이다.</p>
<blockquote>
</blockquote>
<p>🔖 <strong>check_login 및  redirect_to_signin_form 사용위해 import 필요</strong><img src="https://velog.velcdn.com/images/yohan-record/post/0cef336c-3819-47ee-a5b2-efb9960580c0/image.png" alt=""></p>
<blockquote>
<hr>
<ol start="2">
<li>models &gt; order.py 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/ae6cee68-a8d5-474e-9a04-32cca8698100/image.png" alt=""> = order class 생성 후 db연결, insert_one method에 사용하여 product, form, user값을 받아온다.</li>
</ol>
</blockquote>
<p>그 후, form에서 전송된 data들을 받아와서 db에 저장시킨다.</p>
<blockquote>
<hr>
<ol start="3">
<li>order 활성화
<img src="https://velog.velcdn.com/images/yohan-record/post/5975be77-22e2-4c50-8ec7-2f43ffd8a817/image.png" alt=""> = 생성을 했다면, 사용을 위해서는 반드시 import가 필요하다.</li>
</ol>
</blockquote>
<p>  작업을 하면서 자주 까먹는 상황이 발생했고, 반드시 import가 필요하다!!!!</p>
<blockquote>
<hr>
<ol start="4">
<li>주문 생성 API &gt; return 값 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/d29155c2-ed6d-4afc-b7c0-4bf05d94cfe8/image.png" alt="">🔖 *<em>현재 주문테스트는 주문요청 시 db에 값이 저장되는 것을 확인하는 용도이므로, 값만 제대로 전송된다면 주문완료 페이지로 이동시킬 것이다. *</em></li>
</ol>
</blockquote>
<p>  render_template 요청 후 payment_complete.html page로 이동시켜준다.</p>
<blockquote>
<hr>
<ol start="5">
<li>payment_complete.html 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/84a90e11-b801-4b7d-be6f-e63a0e6db113/image.png" alt="">= 주문완료 title및 내용으로 간단하게 페이지 이동 확인 용도로 처리해준다.</li>
</ol>
<hr>
<ol start="6">
<li>form 전송 값 변경
<img src="https://velog.velcdn.com/images/yohan-record/post/60db81a4-3772-43d9-be85-7e2e107a249e/image.png" alt=""> = 어떤 상품을 구매할 것인지에 대한 고유 id값과 /order 로 action값을 요청시킨다.</li>
</ol>
<hr>
<ol start="7">
<li>주문 시 비로그인 처리 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/fa512c84-b855-41aa-a9db-11c588a43b31/image.png" alt=""> = 비로그인 유저가 주문 시 주문 페이지로 이동할 수 없도록 API에서 check를 해두었으므로, 로그인 후 주문을 해야한다.</li>
</ol>
<hr>
<ol start="8">
<li>실제 주문 테스트
<img src="https://velog.velcdn.com/images/yohan-record/post/24e2fa24-91c8-4e37-a78b-e7b3da02e6c6/image.png" alt="">= 주소, 구매자 이름, 연락처 정보를 담아서 주문하기(form 전송) 버튼을 클릭 시 db에 data들이 저장된다.
<img src="https://velog.velcdn.com/images/yohan-record/post/10aa48ed-61b2-4026-8ed5-7f8c96428260/image.png" alt=""> = 주문 요청 시 주문성공 페이지로 이동
<img src="https://velog.velcdn.com/images/yohan-record/post/63baa8f6-a773-4c33-a5df-7f5f15fdf767/image.png" alt=""> = 실제로 db에 order.py 에서 담은 data들을 확인할 수 있다.</li>
</ol>
</blockquote>
<p>이처럼 주문자가 자신의 정보를 입력 후 주문을 요청할 시 요청된 data값들이 db에 정상적으로 담기는 것을 확인할 수 있다.</p>
<p>결제 모듈은 주문완료된 목록과 상세정보를 확인하는 페이지까지 생성 후, 작업해보겠다.</p>
<p>다음 시간에는 주문완료 목록 및 상세정보 확인 페이지를 만들어보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 17편 - 기능별 권한부여]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-17%ED%8E%B8-%EA%B8%B0%EB%8A%A5%EB%B3%84-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-17%ED%8E%B8-%EA%B8%B0%EB%8A%A5%EB%B3%84-%EA%B6%8C%ED%95%9C%EB%B6%80%EC%97%AC</guid>
            <pubDate>Wed, 10 Aug 2022 12:43:53 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-권한부여">1. 권한부여</h2>
<p>✍ 이전 시간에는 관리자(판매자) 와 구매자의 권한을 is_admin key값으로 구분하여 상품등록 페이지를 예시로 들어 테스트를 해보았다.</p>
<p>이제 구분할 수 있는 권한을 생성했으니, 각 페이지 및 기능들의 권한을 부여해 보도록 하겠다.</p>
<blockquote>
<ol>
<li>is_admin 권한 부여
<img src="https://velog.velcdn.com/images/yohan-record/post/b583188b-7ebd-4181-a0e5-693be66693c1/image.png" alt=""> = 상품 등록, 삭제, 수정, 수정 API 에도 적용을 시킨다.</li>
</ol>
</blockquote>
<p>  하지만, 이전 테스트와 마찬가지로 redirect 되는 것보다 관리자를 제외한 나머지 사용자들에게는 보여지지 않는 것이 나을 것이다.</p>
<blockquote>
<hr>
<ol start="2">
<li>is_admin session 값 체크
<img src="https://velog.velcdn.com/images/yohan-record/post/3896e834-80e3-4bce-ae16-a246cce7216b/image.png" alt=""> = 상품 list page의 수정, 삭제 버튼의 경우 <strong>session is_admin 값이 true일 경우 보여주는 방식</strong>을 사용했다.
<img src="https://velog.velcdn.com/images/yohan-record/post/e6c8bc2b-e4da-46f4-bc24-29040a7d3943/image.png" alt=""> = 관리자일 경우에만 보여지는 상태이다.</li>
</ol>
<hr>
<ol start="3">
<li>delete 완료 및 등록완료의 경우 redirect 추가
<img src="https://velog.velcdn.com/images/yohan-record/post/fcfc5143-cdc3-421b-b75e-f00f4b0b1083/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/cdf8e43a-d951-4418-8554-6131c68bb8ab/image.png" alt=""></li>
</ol>
</blockquote>
<p>정리를 해보자면, </p>
<p><strong>비로그인 사용자 및 일반 구매자</strong>의 경우 상품을 보고, 구매하는 행동만 가능하다.</p>
<p><strong>관리자(판매자)</strong>의 경우 상품의 CRUD가 가능하다.</p>
<p>드디어!!!
다음 시간에는 상품을 주문하는 부분을 만들어보겠다!! 🎉</p>
<p>이번 기회에 상품 구매 프로세스를 완벽히 익히고, 결제모듈 연동 및 배포까지 구현하여 기능들도 점차적으로 추가하고, 스타일 작업 및 구조작업(fe)을 통해 여러 테마의 온라인 스토어를 배포시킬 것이다 😎</p>
<p>빠이팅 ^__^</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 16편 - 사용자구분(관리자(판매자)/구매자)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-16%ED%8E%B8-%EC%82%AC%EC%9A%A9%EC%9E%90%EA%B5%AC%EB%B6%84%EA%B4%80%EB%A6%AC%EC%9E%90%ED%8C%90%EB%A7%A4%EC%9E%90%EA%B5%AC%EB%A7%A4%EC%9E%90</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-16%ED%8E%B8-%EC%82%AC%EC%9A%A9%EC%9E%90%EA%B5%AC%EB%B6%84%EA%B4%80%EB%A6%AC%EC%9E%90%ED%8C%90%EB%A7%A4%EC%9E%90%EA%B5%AC%EB%A7%A4%EC%9E%90</guid>
            <pubDate>Wed, 10 Aug 2022 12:18:55 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-사용자-구분-및-권한">1. 사용자 구분 및 권한</h2>
<p>✍ <strong>사용자의 경우</strong>를 나누어 보겠다.
사용자는 <strong>판매자</strong>와 <strong>구매자</strong>로 구분할 수 있다.
<strong>판매자는 상품 CRUD</strong>가 가능해야하며, <strong>구매자는 상품을 확인하고 구매</strong>하는 역할이다.</p>
<p>따라서, 판매자와 달리 <strong>구매자</strong>는 <strong>상품을 보거나 구매만 가능</strong>해야한다.</p>
<p>사용자를 <strong>구분</strong>하고, 각 사용자마다 <strong>권한을 부여</strong>해 요청을 제한해야한다.</p>
<p>우선,
<strong>판매자/구매자</strong> &gt; <strong>Users collection  document</strong> &gt; <strong>is_admin key값</strong>을 대입하여 <strong>true일 시 판매자</strong>, <strong>is_admin 값이 없거나 false일 시 구매자</strong> 로 구분할 것이다.</p>
<p>권한을 생성한 후, <strong>상품등록 메뉴</strong>를 <strong>관리자일 경우</strong>에만 <strong>보여지게</strong> 작업해 보도록 하겠다.</p>
<blockquote>
<p><strong>🧨 관리자/구매자 유저 구분</strong></p>
<ol>
<li>mongodb Compass 접속 및 is_admin 값 부여(관리자)
<img src="https://velog.velcdn.com/images/yohan-record/post/bd3e4975-0f35-47b3-8a15-3d2018beed0f/image.png" alt=""> = 생성 시 string 값은 <strong>boolean</strong>으로 변경 후 생성한다. </li>
</ol>
<p><strong>is_admin</strong> 값으로 <strong>구분</strong>할 것이며, <a href="mailto:test@test.com">test@test.com</a> id는 <strong>admin으로 권한 값이 주어진 것</strong>이다.</p>
<hr>
<ol start="2">
<li>is_admin 으로 판단할 함수 생성(auth.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/f74b2853-4b70-4978-8b88-94d94f66542d/image.png" alt=""> = 우선 판매자와 구매자를 구분하기 위해서는 <strong>로그인 된 상태</strong>여야 하므로 check_login 함수를 호출한다.
만약, user가 존재하지 않는다면 false 값을 return 시켜준다.</li>
</ol>
</blockquote>
<p>  반대의 경우 <strong>is_admin의 값이 존재</strong>한다면, 그 값을 return 시켜준다. ( boolean or false )</p>
<blockquote>
</blockquote>
<p>  get 함수의 경우 <strong>is_admin이 존재하지 않는다면</strong> 오류를 표출하는 것이 아닌, <strong>false 값을 return</strong> 하도록 만들어준다.</p>
<blockquote>
<hr>
<ol start="3">
<li>is_admin import 및 사용 
<img src="https://velog.velcdn.com/images/yohan-record/post/cd2588e0-9685-45bf-88a3-6c04cbb7ee10/image.png" alt=""> = is_admin이 아닐경우, 상품 list page로 redirect 시켜준다.</li>
</ol>
</blockquote>
<p>  올바른 결과라면, <strong><a href="mailto:test@test.com">test@test.com</a>(관리자계정)</strong> 일 경우에는 상품 등록 페이지가 <strong>접속</strong> 될 것이고, <strong>비로그인 및 일반 사용자의 계정</strong>일 경우에는 list page로 계속 redirect 되어 <strong>접속이 불가</strong>할 것이다.</p>
<blockquote>
</blockquote>
<p>  하지만, 접속이 되지 않는 것 보다는, <strong>차라리 등록 버튼이 보이지 않는 편</strong>이 더 나을 것 같아 숨기는 방향으로(관리자만 보여지게) 고민 후 작업해 보았다.</p>
<blockquote>
<hr>
<ol start="4">
<li>로그인 시 세션정보 추가 및 import(controllers &gt; user.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/fdbdbf37-bc3a-4877-b946-e6c3af5edfce/image.png" alt=""> = user가 is_admin일 경우 true값을 추가한다.
<img src="https://velog.velcdn.com/images/yohan-record/post/4694619c-f28d-4895-bd7d-496625344619/image.png" alt=""></li>
</ol>
</blockquote>
<p>🔖 로그아웃의 경우에도 마찬가지이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/b8d2f292-c0e3-48a2-bf16-32b9a131a3eb/image.png" alt=""> = is_admin의 정보를 날려준다(false).</p>
<blockquote>
<hr>
<ol start="5">
<li>is_admin session 값 구분
<img src="https://velog.velcdn.com/images/yohan-record/post/4198074b-da7b-4c0b-8e24-e42e5bc0a1d4/image.png" alt=""></li>
</ol>
</blockquote>
<p><strong>비로그인, 일반 구매자 계정</strong>으로 접속 시에는 상품등록 메뉴 자체가 보이지 않게 되며, <strong>url 로 접속시에도 막아두었으므로 상관이 없다.</strong></p>
<p><strong>관리자의 경우</strong>에만 정상적으로 <strong>접속이 되는 것</strong>이다.</p>
<p>현재 테스트를 위해 권한구분을 제대로 정리하지 못했는데, 다음 시간에는 적용이 필요한 부분들의 권한을 적용시켜보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 15편 - 사용자구분(로그인/비로그인)]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-15%ED%8E%B8-%EC%82%AC%EC%9A%A9%EC%9E%90%EA%B5%AC%EB%B6%84%EB%A1%9C%EA%B7%B8%EC%9D%B8%EB%B9%84%EB%A1%9C%EA%B7%B8%EC%9D%B8</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-15%ED%8E%B8-%EC%82%AC%EC%9A%A9%EC%9E%90%EA%B5%AC%EB%B6%84%EB%A1%9C%EA%B7%B8%EC%9D%B8%EB%B9%84%EB%A1%9C%EA%B7%B8%EC%9D%B8</guid>
            <pubDate>Wed, 10 Aug 2022 11:40:40 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-사용자-구분-및-권한로그인비로그인">1. 사용자 구분 및 권한(로그인/비로그인)</h2>
<p>✍ <strong>로그인 사용자</strong>와 <strong>비로그인 사용자</strong> 로 구분지을 수 있다.</p>
<p><strong>로그인을 한 사용자</strong>는 <strong>상품을 구매</strong>하거나 <strong>로그아웃</strong>을 할 수 있지만, <strong>로그인을 하지않은 사용자</strong>는 <strong>상품을 보는 것만 가능</strong>하다.</p>
<p>이 또한 <strong>구분 후 요청을 제한</strong>해야한다. 
작업 전 굴러가는 로직을 생각한 후 작업해 보겠다.</p>
<p>우선,</p>
<p><strong>로그인/비로그인 사용자</strong> &gt; session 존재유무에 따라 구분할 수 있겠다.</p>
<p>현재 세션으로 <strong>로그인 되었을 시 로그아웃</strong>이 나오고, <strong>로그아웃 시 로그인</strong>이 보이도록 해두었다.</p>
<p>이와 별도로, <strong>session이 처리되지 않은 로그아웃 버튼</strong>을 하나 생성하여 <strong>미로그인 상태에서 로그아웃</strong>을 클릭 시 <strong>로그인 후 이용가능하도록 권한을 부여</strong>할 것이다.</p>
<blockquote>
<p><strong>🧨 로그인 유저 구분</strong></p>
<ol>
<li><strong>controllers &gt; auth.py file</strong> 생성
= user controllers(controllers &gt; user.py) 에서 사용하여도 되지만, 로그아웃 뿐만이 아닌 등록 및 구매에서도 사용될 예정이므로 공통된 함수로 사용해 준다.</li>
</ol>
<hr>
</blockquote>
<ol start="2">
<li><strong>로그인을 체크할 함수 생성</strong><blockquote>
</blockquote>
📍 비로그인의 경우<img src="https://velog.velcdn.com/images/yohan-record/post/d9061128-fe16-484d-817b-2f343dae711a/image.png" alt=""> = 로그인을 했는지 안했는지 session에 대한 정보를 가지고 확인.
즉, session에 user_id 값이 있는지 없는지 구분하고, 값이 없다면 false를 return(로그인 한 유저가 아니다.)<blockquote>
<hr>
<p>📍로그인의 경우<img src="https://velog.velcdn.com/images/yohan-record/post/3b1b033a-7b31-4123-a0ec-3fc208747be2/image.png" alt=""> = session에 있는user_id의 값을 가지고 user를 찾는다. </p>
<hr>
</blockquote>
</li>
<li><strong>find_one 함수 생성</strong>
<img src="https://velog.velcdn.com/images/yohan-record/post/793b3b06-9d8f-4e39-b174-0a2e3d9153b4/image.png" alt=""> = user_id를 받아주고, _id값이 user_id와 같은 user를 찾게 된다.
그 후 user가 없다면 false를 return하고, 존재한다면 user값을 return 시켜준다.<blockquote>
<hr>
</blockquote>
</li>
<li><strong>auth.py &gt; user</strong> 값 전달
<img src="https://velog.velcdn.com/images/yohan-record/post/b21a134d-5102-44b8-a07e-feda494e1347/image.png" alt=""> = find_one 함수에 session id 값이 들어가면 user가 나오거나 false가 나오게 된다.<blockquote>
</blockquote>
check_login 함수를 사용할 때 최종 값은 user 또는 false 일 것이다.<blockquote>
<hr>
</blockquote>
</li>
<li>controllers &gt; user.py -&gt; <strong>check_login</strong> 함수 실행
<img src="https://velog.velcdn.com/images/yohan-record/post/ad70522f-b7e4-4259-b979-2806cd6a30bd/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/6fb85dab-a5bd-4a22-8814-634545600601/image.png" alt=""> = check_login 함수 실행을 위해 import 도 포함<blockquote>
<hr>
</blockquote>
</li>
<li>check_login을 할때마다 사용할 함수 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/06c0e2b3-7c62-4ca6-8f7a-3f0cdfb69b1a/image.png" alt=""> = login page로 이동시키기 위한 함수 생성
여기서 url_for 내부의 <strong>signin_form</strong> 의 경우 user controllers 에 미리 생성해 둔 코드이다.
flash 도 추가하여 alert 후 이동되도록 처리해 두었다.<blockquote>
</blockquote>
<img src="https://velog.velcdn.com/images/yohan-record/post/d1d5a420-687f-4034-949d-2959945d37c9/image.png" alt=""><blockquote>
<hr>
</blockquote>
</li>
<li>redirect_to_signin_form 함수 활용 및 import
<img src="https://velog.velcdn.com/images/yohan-record/post/ff976f3d-b7e7-4cd5-ab6e-2d9feb99bf4e/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/9bcaeef6-41da-4344-b21a-3ddc68dc7b2a/image.png" alt=""> = user가 없다면 redirect 함수 실행 및 로그인 page 이동<blockquote>
<hr>
</blockquote>
</li>
<li>미로그인 유저가 로그아웃 클릭 시 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/020cca04-e5b9-471f-9c06-8a8e7a7c572d/image.png" alt="">
<img src="https://velog.velcdn.com/images/yohan-record/post/04970d2b-0724-4963-9e04-ec144b2bdc5c/image.png" alt=""> = 로그인이 되지 않은 유저기에 else에 걸려 flash 실행 및 로그인 페이지로 이동된다.</li>
</ol>
<p>이렇게 로그인과 비로그인을 공통적인 함수를 생성하여 구분할 수 있게 만들어 두었다.</p>
<p>로그인 후 사용가능한 페이지를 구분하여 권한을 부여하면 될 것 같다.</p>
<p>다음 시간에는 판매자(관리자)와 구매자를 구분하여 권한을 부여해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 14편 - 로그인]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-14%ED%8E%B8-%EB%A1%9C%EA%B7%B8%EC%9D%B8</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-14%ED%8E%B8-%EB%A1%9C%EA%B7%B8%EC%9D%B8</guid>
            <pubDate>Mon, 08 Aug 2022 13:58:45 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-로그인">1. 로그인</h2>
<p>✍ 이메일 패스워드 체크 후 값이 유효한 경우 <strong>session id</strong>와 <strong>user id</strong> 를 저장하고, <strong>session id값을 web browser</strong> 에 전달한다.</p>
<p>이후, web browser는 <strong>요청을 할 때마다 session id값</strong>을 <strong>flask에 전달</strong>하고 <strong>session id값이 존재</strong>하면 <strong>login 상태</strong>로 판단하게 된다.</p>
<blockquote>
<ol>
<li>로그인 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/126b5f95-5083-481a-b67d-8ed89384805a/image.png" alt=""> = route는 /singin 주소값 및 singin 함수 생성. form_data도 받아온다.</li>
</ol>
<hr>
<ol start="2">
<li>받은 form data를 이용하여 로그인 판별
<img src="https://velog.velcdn.com/images/yohan-record/post/52560b2f-966b-4757-a4ef-6203afa697b0/image.png" alt="">= sign_in 함수는 form_data의 email과 password 값을 check하여 정상적인 로그인이라면 user 의 정보를 가져올 것이고, 아니라면 로그인이 제대로 작동되지 않았다는 값을 return 시킬 것이다.</li>
</ol>
<hr>
<ol start="3">
<li>models &gt; user.py sign_in 함수생성
<img src="https://velog.velcdn.com/images/yohan-record/post/30128ca4-a23f-490a-8b02-8de883999b19/image.png" alt=""></li>
</ol>
<hr>
<ol start="4">
<li>user 찾기
<img src="https://velog.velcdn.com/images/yohan-record/post/39e786d1-681d-4274-aa4c-25edb4ade728/image.png" alt=""> = login 할 시 전달된 data email이 documnet에 존재한다면 users document에서 가져와서 user에 담는다.</li>
</ol>
<hr>
<ol start="5">
<li>존재여부에 따른 처리방식
<img src="https://velog.velcdn.com/images/yohan-record/post/ae1a4a31-2174-46ca-b32c-0a91c06241a6/image.png" alt="">= 만약 email document data가 없다면 false값을 return 해 줄것이고, 존재한다면 다음순서인 password를 check 해 주어야 한다.</li>
</ol>
</blockquote>
<p>user의 password와 전달받은 password 의 값이 같지 않다면, return false를 시켜준다.</p>
<blockquote>
</blockquote>
<p>🔖 현재 <strong>check_password_hash</strong> 라는 값은 db에 저장될 password를 암호화 시켜주기 위해 사용한 것이다.</p>
<blockquote>
</blockquote>
<p>자세한 설명은 뒤에 게시될 것이므로, 그 값이  password 여부를 체크하는데 사용되었다 정도로 이해하고 넘어가면 될 것 같다.</p>
<blockquote>
</blockquote>
<p>참고)<img src="https://velog.velcdn.com/images/yohan-record/post/26774d29-c9f4-4412-b30b-eb10399b8399/image.png" alt="">= 즉, 회원가입한 email이 없거나 password 가 일치하지 않으면 false 값을 반환할것이고, 둘다 일치한다면 찾은 document user 정보를 return 한다는 함수이다.</p>
<blockquote>
<hr>
<ol start="6">
<li>API에서 존재여부에 따른 처리
<img src="https://velog.velcdn.com/images/yohan-record/post/c22e00dd-d30b-4bd5-bd30-0249ac778890/image.png" alt=""> = 만약, user가 없다면 flash message 및 회원가입 페이지로 return 시키고(추후 html file 생성 예정)</li>
</ol>
</blockquote>
<p>존재한다면 session이용 (import 필요 = from flask import request, render_template, flash, redirect, url_for, <strong>session</strong>)</p>
<blockquote>
<p>즉, session 정보에 user_id라는 key값으로 user id를 문자열로 저장한다는 의미이다.</p>
</blockquote>
<p>로그인이 성공한다면, list page로 redirect 시켜준다.</p>
<blockquote>
<hr>
<ol start="7">
<li>password 암호화 (5번 순서 참고)
= 기존 회원정보 db를 참고할 시 password 가 &quot;1234&quot; 로 가입되어 있다면 db에서도 &quot;1234&quot; 로 보여진다.</li>
</ol>
</blockquote>
<p>그러하여, 암호화 작업을 통해 회원들의 password 가 노출되지 않도록 암호화 시켜주는 작업을 해보겠다.</p>
<blockquote>
</blockquote>
<p><strong>7-1. models &gt; user.py file open 및 import</strong>
<img src="https://velog.velcdn.com/images/yohan-record/post/8626758d-14ec-4999-bfb5-285a55cfc51a/image.png" alt=""> = <strong>generate_password_hash</strong> -&gt; 암호화된 password</p>
<blockquote>
</blockquote>
<p>= <strong>check_password_hash</strong> -&gt; 암호화된 password check</p>
<blockquote>
<hr>
<p><strong>7-2. 저장 시 암호화 처리</strong><img src="https://velog.velcdn.com/images/yohan-record/post/61cdac9a-8554-4a33-af42-662fe74f7cf9/image.png" alt=""></p>
<hr>
<p><strong>7-3. password 비교</strong>
check_password_hash 사용하여 기존 암호화된 password 와 전달받은 암호화되지 않은 password를 넣어 check 후 일치할 시 true return/ 일치하지 않을 시 false return
<img src="https://velog.velcdn.com/images/yohan-record/post/2f167bf6-a4c4-46db-8301-7e007deccdc9/image.png" alt=""></p>
</blockquote>
<p>이렇게 암호화 작업까지 마친 후, 회원가입 진행 시 암호화된 password 가 db에 저장될 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/379ef82c-c69b-450d-8296-e72fb8eadc8e/image.png" alt=""></p>
<blockquote>
<hr>
<ol start="8">
<li>login page API 생성 및 html file 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/672f6273-ddf9-4a51-bf59-e9a548ed3b82/image.png" alt=""></li>
</ol>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/e76fd020-e611-4211-aa56-641d705bcae4/image.png" alt=""> = page 내부의 form action 값만 signin으로 변경</p>
<blockquote>
<hr>
<ol start="9">
<li>로그인 여부 파악 후 표시
= <strong>로그인이 되지 않았을 때</strong>는 로그인 메뉴가 나타나야하고, <strong>로그인이 되었을 경우</strong>에는 로그아웃 메뉴가 나타나야 한다.</li>
</ol>
</blockquote>
<p>if 구문 및 저장한 session 값으로 비교가 가능할 것 같다.
직접 구현해 보면서 코드를 작성해 보겠다.</p>
<blockquote>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/edd7ebdf-7f9f-4f9a-9102-013af5b0bb0c/image.png" alt=""> = user_id 가 존재한다면 로그아웃, 존재하지 않는다면 로그인이 표시 될 것이다.</p>
<blockquote>
<hr>
<ol start="10">
<li>로그인 시 user_id 출력
<img src="https://velog.velcdn.com/images/yohan-record/post/bf0e3fa1-c761-465b-b5b5-1e12da38ab14/image.png" alt=""> = db에 저장된 고유 id값이 출력될 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/3bc64adf-12a5-4235-87f9-616c25703125/image.png" alt="">
<img src="https://velog.velcdn.com/images/yohan-record/post/63fa7259-a6e0-4b52-85ec-48892d15b205/image.png" alt=""></li>
</ol>
<hr>
<ol start="11">
<li>로그아웃 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/3a54399d-8a8c-4c4a-a9e6-59ce26a10cb5/image.png" alt=""> = signin 이 아닌, signout이 될 것이다.</li>
</ol>
<hr>
<p>controllers &gt; user.py &gt; route 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/ee23483f-6f02-437b-a8ef-084a75a072c3/image.png" alt="">= 저장해 둔 이용권 정보를 없애면, 이용권을 주더라도 정보가 없다고 판단하여 자연적으로 로그아웃 상태가 된다.
로그아웃이 된다면 list 가 보이도록 redirect 시켜두었다.</p>
</blockquote>
<p>즉, <strong>로그인이 성공</strong>한다면 <strong>로그인 메뉴가 로그아웃 메뉴</strong>로 변경되고, <strong>로그아웃을 클릭</strong> 시 <strong>session이 초기화 됨에 따라 로그아웃</strong>이 되고, <strong>로그인 메뉴</strong>가 보이게 된다.</p>
<p>이렇게 로그인, 로그아웃을 구성하였다😎</p>
<p>다음 시간에는 회원관리, 사용자 권한과 관련된 부분을 구현해 보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 13편 - 회원가입]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-13%ED%8E%B8-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-13%ED%8E%B8-%ED%9A%8C%EC%9B%90%EA%B0%80%EC%9E%85</guid>
            <pubDate>Mon, 08 Aug 2022 12:38:24 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-회원가입">1. 회원가입</h2>
<p>✍  작업 전, 새로운 상품을 등록하는 로직처럼 새로운 사용자를 등록하면 크게 다를 게 없을 것 같다는 생각이 들었다. </p>
<p>결과적으로 회원가입은 <strong>상품 등록과 유사</strong>하다. <strong>상품 -&gt; 사용자</strong>가 되는 것이고, product에서 사용한 <strong>controllers 및 models</strong> 도 User로 세팅하면 되는 것이다.</p>
<p>새로운 상품 등록이 아닌, <strong>새로운 사용자가 등록</strong>한다고 생각하면 쉽게 해결할 수 있으리라 판단했다.</p>
<blockquote>
<ol>
<li>blueprint 경로 세팅
<img src="https://velog.velcdn.com/images/yohan-record/post/01f50ec6-b997-46e1-9d4b-8f6110060c04/image.png" alt="">= products 세팅 시와 동일하게 user도 생성해준다.</li>
</ol>
<hr>
<ol start="2">
<li>controllers &gt; product.py copy 후 user.py 생성</li>
</ol>
<hr>
<ol start="3">
<li>사용하는 import 만 남겨두고, product 값은 user로 변경
<img src="https://velog.velcdn.com/images/yohan-record/post/2735a5a7-44fe-4bd5-b475-623ab0daf941/image.png" alt=""></li>
</ol>
<hr>
<ol start="4">
<li>models &gt; product.py copy 후 user.py 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/5a7193f1-0cac-4ff7-a87f-5cdfec1baf6d/image.png" alt=""> = product가 아닌, <strong>user class 생성</strong> (3번 항목의 3번째 줄 <strong>models &gt; user.py</strong> 의 <strong>User Class</strong> 가 <strong>import</strong> 되는 것이다.)</li>
</ol>
<hr>
<ol start="5">
<li>app.py -&gt; user blueprint 등록
<img src="https://velog.velcdn.com/images/yohan-record/post/e4b44b88-7254-4953-8973-4481669dd1c3/image.png" alt=""></li>
</ol>
<hr>
<ol start="6">
<li>회원가입 등록 페이지 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/b70a2a2a-55cd-4b90-9fe0-099c18ec2f3e/image.png" alt=""> = /users/form 입력 시  users/product_form.html 랜더링</li>
</ol>
<hr>
<ol start="7">
<li>회원가입 data 전달 및 요청 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/797ebca5-08e7-4039-9087-c971021e7848/image.png" alt=""> = form_data를 User class에 insert 시켜준다.(/models/user.py)</li>
</ol>
<hr>
<ol start="8">
<li>models &gt; user.py insert_one 수정
<img src="https://velog.velcdn.com/images/yohan-record/post/8c8f897c-5c97-42c9-b6c3-55db1d675b97/image.png" alt=""> = 지금까지의 흐름도를 이해하고 넘어가려고 한다</li>
</ol>
<p>회원가입 정보 입력 후  회원가입 버튼 클릭 시 /users/signup 주소로 넘어감과 동시에 post방식(회원정보가 주소창에 보여지는것은 옳지 않음) 으로 User Class에 form_data를 던져준다.</p>
</blockquote>
<p>그럼, User Class의 insert_one에서 form_data를 받아 해당 정보들을 users collection으로 생성 후 document를 집어넣어준다.</p>
<blockquote>
<hr>
<ol start="9">
<li>templates &gt; user_form.html file 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/02d71420-4328-45c1-9950-5cc0fb185c6c/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/fbb15bcc-040b-467b-bb3d-a60ac8d6e7b4/image.png" alt=""> = 파일 생성 후 form으로 넘어갈 action 값을 signup(controllers/user.py 에 만들어 둔 경로) 로 전송 및 항목에 맞게 form 내부 input 값 변경</li>
</ol>
<hr>
<ol start="10">
<li>data 전송 후 확인(mongodb compass)
<img src="https://velog.velcdn.com/images/yohan-record/post/2584c27a-77ef-428f-a6fd-caa9bba276f5/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/93bc8535-24d1-4352-8aa0-70349fa14540/image.png" alt=""> = 가입하고자 하는 이메일 및 패스워드 입력 후 form값을 전송 시(버튼 클릭 시) db에 users collection 생성 및 전송한 data 값이 들어오게 된다.</li>
</ol>
</blockquote>
<p>하지만, password 와 password 확인이 <strong>다를 경우</strong>에도 회원가입이 <strong>정상적</strong>으로 이루어졌을 것이며, <strong>같은 email</strong> 로 회원가입 시에도 <strong>정상적으로 진행</strong>되었을 것이다. 또한 data를 입력하지 않은 상태에서 form 값을 넘길 경우에도 문제가 될 것이다.</p>
<blockquote>
</blockquote>
<p><strong>당연하다. 내가 별다른 처리를 안했다(?)</strong>
이제 처리를 해보겠다 😉</p>
<blockquote>
<hr>
<ol start="11">
<li>data 유무 및 중복검사 체크
<img src="https://velog.velcdn.com/images/yohan-record/post/d99a5bfe-9b8b-48f4-9456-b9d1e5ddc746/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/f970f2cc-243e-4988-8122-6d10e34068b3/image.png" alt=""> = 간단하게 if문으로 <strong>일치하지 않을 경우</strong> 넘어가지 못하게 방지하였고, html 코드 상에서 required 를 사용함으로 <strong>필수적으로 입력하도록</strong> 처리해 두었다.</li>
</ol>
</blockquote>
<p>  하지만, 이메일 체크의 경우는 form_data의 이메일 존재여부를 파악한 후 data를 비교하여 처리해야 한다.</p>
<blockquote>
</blockquote>
<p>  우선, 비교문을 작성한다.<img src="https://velog.velcdn.com/images/yohan-record/post/e7dce309-2166-4083-9645-91678f05f252/image.png" alt=""></p>
<blockquote>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/26daea83-c067-41cd-8b1c-59b71a713247/image.png" alt="">= db에 같은 email이 들어온 것이 있는지 파악 후,
만약 <strong>있다면</strong> email을 사용하면 안되므로 <strong>false</strong> 값을 반환하고, <strong>없다면 true</strong>를 반환시킨다.</p>
<hr>
<ol start="12">
<li>flash 사용
<img src="https://velog.velcdn.com/images/yohan-record/post/b2972745-8f34-4bc3-81f8-ee234b9d06d2/image.png" alt="">
= 만약 flash를 호출한 message가 존재한다면 <strong>해당 message를 alert 창으로</strong> 띄워준다. (flash 구문 11번 참조)</li>
</ol>
</blockquote>
<p> 🔖 구문 중 <strong>%</strong> 와 <strong>{</strong> 또는 <strong>}</strong> 사이에 <strong>공백이 없어야 한다.</strong></p>
<blockquote>
</blockquote>
<p><strong>하지만 error 가 발생할 것</strong>이다. 😵‍💫</p>
<blockquote>
</blockquote>
<p>session을 사용하여 작업하는 것인데, secret key가 없기 때문이다.
그러므로, app.py에서 secret_key를 설정해 주어야 한다.
<img src="https://velog.velcdn.com/images/yohan-record/post/960dbc41-67c8-4051-b665-64cb9e7ea098/image.png" alt="">그 후, user_form 에 만든 alert 가 불릴 수 있도록, flash 하단에 각각 render 시켜준다.
<img src="https://velog.velcdn.com/images/yohan-record/post/9f689251-95d4-4124-984b-e02d346a312b/image.png" alt=""></p>
<blockquote>
<hr>
<ol start="13">
<li>회원가입 완료 후 list page 이동
<img src="https://velog.velcdn.com/images/yohan-record/post/a3f626fb-4b18-4100-aa95-ffed27082b70/image.png" alt=""> = 우선 product blueprint 를 가져온다. redirect 를 시키기 위해서는 product 가 필요하기 때문이다.</li>
</ol>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/b619caa8-f4bc-44ab-8947-372136332719/image.png" alt=""> = redirect 시 필요한 redirect 및 url_for import</p>
<hr>
<p><img src="blob:https://velog.io/3ff4ece8-df36-406b-b224-3e7f37d57dba" alt="업로드중..">= products redirect</p>
</blockquote>
<p>이로써 회원가입 버튼을 누를 시 form data가 전송되며 몇가지 구문으로 값 비교 후 db에 저장될 것이다 🎉</p>
<p>다음시간에는 저장된 member 값을 활용하기 위해 로그인을 구현해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 12편 - 상품 상세페이지]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-12%ED%8E%B8-%EC%83%81%ED%92%88-%EC%83%81%EC%84%B8%ED%8E%98%EC%9D%B4%EC%A7%80</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-12%ED%8E%B8-%EC%83%81%ED%92%88-%EC%83%81%EC%84%B8%ED%8E%98%EC%9D%B4%EC%A7%80</guid>
            <pubDate>Thu, 04 Aug 2022 12:36:09 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품-상세">1. 상품 상세</h2>
<p>✍ 상품 상세페이지는 수정과 많이 다르지 않다.
상품 정보 수정페이지는 <strong>특정상품의 고유번호(id)</strong> 를 주소로 받아서 MongoDB에서 해당하는 <strong>document 정보</strong>를 가져와서 <strong>product.html 과 함께 반환</strong>해 주었다.</p>
<p>마찬가지로, <strong>상품정보를 html 에 넘겨서 보여주는 것</strong>이므로 쉽게 처리할 수 있을 것이라고 판단했다. <del>(판단이 맞길 😅)</del></p>
<blockquote>
<ol>
<li>상품 상세 정보 페이지 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/5c9151fc-4e6a-4dd8-b6c1-0091b7d36940/image.png" alt=""> = find_one method를 통하여 product_id를 가져온다.</li>
</ol>
<hr>
<p>📍 <strong>id가 들어가면 _id가 같은 document 를 가져와서 return 해주고(/modles/product.py)</strong><img src="https://velog.velcdn.com/images/yohan-record/post/564cae3a-d803-4692-bcb4-a95089c3ff78/image.png" alt=""></p>
<hr>
<p>정보가 불러와 지게 되는 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/0841e107-0f3b-4ffc-bdc0-703b4b5fd8cc/image.png" alt=""></p>
</blockquote>
<p>그 후 return template에 product.html file을 생성한다.</p>
<blockquote>
<hr>
<ol start="2">
<li>html file 구조 변경 및 style 작업(bootstrap)
<img src="https://velog.velcdn.com/images/yohan-record/post/6bf3a42e-3a8d-4488-9bec-d1d6d582f0e1/image.png" alt=""> = 해당 bootstrap 내용은 앞전에도 다뤘으므로 따로 정리해서 올리지 않겠다. 
쉽게 설명하자면 bootstrap의 card demo를 가지고 붙여넣은 뒤, data 값만 db에서 땡겨와 주면 끝이다. 😎
<img src="https://velog.velcdn.com/images/yohan-record/post/261b5346-a1b3-4704-a232-9268858452a8/image.png" alt="">
🔖 list page 에서도 view 페이지로 링크 이동이 되어야 하므로, href 값을 <strong>href=&quot;/products/{{product[&#39;_id&#39;]}}/detail&quot;</strong> detail 로 이동되도록 설정한다.</li>
</ol>
</blockquote>
<p>드디어 CRUD가 가능한 상품 페이지가 끝이 났다!</p>
<p>반틈정도 갖춰진 상태인데,
회원가입 및 로그인도 작동이 되어야하고,
권한에 맞게 관리자만 상품을 삭제, 수정 및 등록을 할 수 있어야하며,
PG사 결제도 추가하여야 하고,
사이트 배포도 남아있다. 😎😎</p>
<p>평소에 해보고싶었던 작업물인데, 개강 전에 작업할 수 있게 되어 행복하다 🎉 
<strong>(회사에서도 코딩하고 퇴근하고도 코딩하려니 속이 안좋긴 하지만 재미는 있다 ㅎㅎ)</strong></p>
<p>3째주부터 시작되는 대기중인 사이드프로젝트의 일정을 맞추기 위해서는 다음주까지는 끝내야 하지 않을까 싶다.</p>
<p>오류가 발생하더라도 빨리 처리해서 무사히 완료하고싶다.</p>
<p>다음 시간에는 member쪽 회원가입 및 로그인을 구현해 보겠다 !!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 11편 - 상품 수정]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-10%ED%8E%B8-%EC%83%81%ED%92%88-%EC%88%98%EC%A0%95</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-10%ED%8E%B8-%EC%83%81%ED%92%88-%EC%88%98%EC%A0%95</guid>
            <pubDate>Thu, 04 Aug 2022 12:01:32 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품-수정">1. 상품 수정</h2>
<p>✍ 상품 수정은 등록과 매우 유사하다. 변경하고싶은 <strong>특정 상품의 고유번호</strong>를 <strong>주소값</strong>에 담고 update 주소를 정의한다. <strong>flask가 주소를 요청</strong>받으면 <strong>API 함수를 호출</strong>하고, 특정상품의 고유번호를 가진 <strong>product document 상품</strong>을 찾아 <strong>수정</strong>시켜 주는 것이다.</p>
<blockquote>
<ol>
<li>상품 수정 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/f6356ad3-897e-4ae9-95e1-ba8754e83318/image.png" alt=""> = route를 product_id/update 주소로 요청하며, update 함수를 사용함과 동시에 product_id값을 받아준다.</li>
</ol>
<hr>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/05aa9354-f608-436c-8d3c-fab13a5f4a97/image.png" alt=""> = 상품 등록과 유사하게 동일한 data 값을 받아온다.
  하지만 <strong>등록과는 다른 점</strong>이 있다. 수정을 하는 경우에는 <strong>img file을 수정하지 않을 수도 있을 것</strong>이다. </p>
</blockquote>
<p>  수정을 하지 않는 경우에는 <strong>upload를 하지 않을 것</strong>이고, <strong>thumbnail 및 detail img가 아무것도 존재하지 않을 것</strong>이다.</p>
<blockquote>
</blockquote>
<p>  그러므로,  if문으로 <strong>존재여부를 파악</strong>하여 <strong>있다면</strong> upload 시키도록 작업을 해주었다.
  🔖 <strong>등록도 동일하게 if문으로 처리해준다.</strong></p>
<blockquote>
<hr>
<p>  하지만, 수정을 하지 않는 경우에는 if문이 동작하지 않고, 최종적으로 update_one 함수가 실행될 때 thumbnail_img_url 및 detail_img_url 을 정의할 수 없어 오류가 발생할 것이다.
  <img src="https://velog.velcdn.com/images/yohan-record/post/d3c0bea9-2a26-4e34-9f21-40591b569e5e/image.png" alt=""></p>
<hr>
<p>이러한 상황을 예방하기 위해 기본적으로 정의를 해두어서 <strong>undefined 가 발생하지 않도록 변수를 정의해</strong> 두었다.
  <img src="https://velog.velcdn.com/images/yohan-record/post/276f1d32-ea80-4e8d-a9f5-087c31850fe5/image.png" alt=""></p>
<hr>
<p>  그 후, 데이터를 받아와서 저장해야 하므로 update_one 이라는 함수를 만들어 저장하겠다.
  필요한 data는 어떤 상품을 삭제할 지 파악해야 하므로 고유 id값과(product_id), form_data, thumbnail_img_url 과 detail_img_url 값을 받아오겠다.</p>
</blockquote>
<p>  <img src="https://velog.velcdn.com/images/yohan-record/post/7c2a4330-4f57-4feb-a3e9-bf13577d96ec/image.png" alt=""></p>
<blockquote>
<hr>
<ol start="2">
<li>update_one 함수 생성 (models &gt; product.py)</li>
</ol>
</blockquote>
<p><strong>📍 update_one 함수 생성(요청한 data값 받아옴) 및 mongodb connect<img src="https://velog.velcdn.com/images/yohan-record/post/60c539ce-d36c-4642-82ef-8205fcf67b51/image.png" alt=""></strong></p>
<blockquote>
<hr>
<p>📍 <strong>생성의 경우 insert_one으로 정보들을 저장하였으나, update_one 함수를 사용하여 $set 부분에 정보를 전달하는 코드를 작성한다.</strong><img src="https://velog.velcdn.com/images/yohan-record/post/4c83ddc8-feb5-4934-8522-93088d8bed3f/image.png" alt=""></p>
<hr>
<p><strong>📍 어떤 document(상품)을 수정할 것인지 구분이 필요하므로, 전달받은 ObjectId 값으로 product id를 찾는다.</strong><img src="https://velog.velcdn.com/images/yohan-record/post/010349b3-c605-40bd-b72c-7e502ab43157/image.png" alt=""></p>
<hr>
<p><strong>📍 기존의 정보와 새로 들어온 정보들이 구별되어 저장되어야 한다. 
(수정하는 사람의 입장에서는 data를 변경하지 않을 수도 있으므로 빈값으로 update 되지 않도록 해준다.)</strong>
<img src="https://velog.velcdn.com/images/yohan-record/post/5d0dbae2-0fc8-480c-9bdd-019f07d493a5/image.png" alt=""></p>
<hr>
<p>** 📍 img 처리 **
이미지가 <strong>존재</strong>한다면, new_product 에 img를 url 로 수정해준다. 즉, 새로운 수정된 img 의 url값을 넣어준다는 의미이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/c0969357-6d40-4904-837f-92e9b7ee0c30/image.png" alt=""></p>
<hr>
<p>  ** 📍 return 값 생성 **
  <img src="https://velog.velcdn.com/images/yohan-record/post/21a9cdf7-2a12-4790-acf4-269a49dbc28a/image.png" alt=""></p>
<hr>
<ol start="3">
<li>상품 page 생성</li>
</ol>
</blockquote>
<p>  ** 📍 상품 정보 수정 페이지 API 생성 ** <img src="https://velog.velcdn.com/images/yohan-record/post/b2a92033-dc09-48f4-9ddb-ef211440e32a/image.png" alt="">= <strong>어떤 상품을 수정</strong>할 지 파악해야 하므로 <strong>고유 id값/edit</strong> 으로 주소를 정의하였다. 
  <strong>find_one</strong> 이란 수정 page에 접속했을 때 어떤 정보가 기존에 작성이 되어있는지 <strong>확인 후 수정</strong>을 거쳐야하므로 <strong>id값을 넘겨서 document</strong>를 가져올 것이다.</p>
<blockquote>
<hr>
<p>   ** 📍 models &gt; product.py -&gt; find_one 생성  **
<img src="https://velog.velcdn.com/images/yohan-record/post/92dcda78-d959-4045-9747-b2d63e5705b2/image.png" alt=""> = id값 및 db 사용하겠다고 선언하였다. 즉, _id가 넘겨준 id과 같은 document를 찾아서 가져온다. 
    그 후, product document를 return 시 (controllers &gt; product.py)
    return 받은 document로 html file과 함께 web browser에 보여질 것이다.<img src="https://velog.velcdn.com/images/yohan-record/post/82460822-0e56-482e-9b59-112f36773c3b/image.png" alt=""></p>
<hr>
<p>  ** 📍 Compass 접속 및 product document id값 주소창 입력 **
  <img src="https://velog.velcdn.com/images/yohan-record/post/6b0220fb-cfb3-41b5-a93d-1c6b26a01e14/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/86b07303-00d6-4181-bec7-a9edc39553d3/image.png" alt=""> = html file에 출력구문을 작성하였다면, 해당 product document의 정보값이 출력 될 것이다. </p>
<hr>
<p>** 📍 product_edit.html file 커스텀 **
<img src="https://velog.velcdn.com/images/yohan-record/post/c9af1b25-9b5a-4296-a92c-71adb2d910ec/image.png" alt=""> = 등록폼과 유사한 구조 및 스타일이며, 등록과 다른 부분은 input에 data가 포함된 상태인 것이다.</p>
</blockquote>
<p>data를 추가하기 위해서는 name으로 예시를 들자면 ** value=&quot;{{product[&#39;name&#39;]}}&quot; ** 값을 추가시켜주면 가져온 data값이 뿌려진다.</p>
<blockquote>
</blockquote>
<p>update 를 클릭 시 action 값은 ** /products/{{product[&#39;_id&#39;]}}/update ** 주소로 전달되고 controllers &gt; product.py -&gt; 상품 정보 수정 API가 호출이 되면서 return 값 또한 출력 될 것이다.</p>
<blockquote>
<hr>
<p>** 📍update 후 list page 이동 및 import **
<img src="https://velog.velcdn.com/images/yohan-record/post/ae7f1bfa-6e64-44af-b500-e03c7d001a7f/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/c5d3fb77-4889-4dbe-91b3-bae3310a66af/image.png" alt=""> = redirect를 <strong>product 안에 있는 get_products 함수</strong>를 호출시켜준다는 의미이다.
즉, <strong>수정이 되면 상품 리스트 조회 page 로 이동</strong>시켜준다는 코드이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/99d6361c-3f46-43cc-b8d2-799fa85ff87a/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>= 이와 같이 정상적으로 list page로 <strong>redirect됨과 동시에 data가 수정된 부분</strong>을 확인할 수 있다.</p>
<blockquote>
</blockquote>
<p>🔖 list_page의 edit 버튼에도 ** /products/{{product[&#39;_id&#39;]}}/edit ** edit 페이지로 이동시켜주는 링크를 추가시켰다.</p>
<p>오늘따라 집중이 잘 되지않아 등록과 거의 유사한 부분이 많았음에도 불구하고 몇번이고 반복해서 들었던 것 같다 😵‍💫</p>
<p>그래도 확실히 이해를 하고 넘어갈 수 있어 다행인 것 같다 ^^...........</p>
<p>다음 시간에는 상품 detail page를 작업해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 10편 - 상품 삭제]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-10%ED%8E%B8-%EC%83%81%ED%92%88-%EC%82%AD%EC%A0%9C</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-10%ED%8E%B8-%EC%83%81%ED%92%88-%EC%82%AD%EC%A0%9C</guid>
            <pubDate>Wed, 03 Aug 2022 13:36:47 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품-삭제">1. 상품 삭제</h2>
<p>✍ 등록된 상품을 list에서 확인 후 삭제하는 기능을 구현해 보도록 하겠다.
큰 logic을 구상해보면 상품 삭제를 위해 버튼을 클릭 시 삭제하고자 하는 상품의 고유id값을 매개변수로 던져주고, 삭제가 진행되는 과정이다.</p>
<blockquote>
<ol>
<li>상품 삭제 API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/abc4db33-9e56-4574-800a-52e24d2a24bd/image.png" alt=""> = 상품 삭제 요청을 받기 위해서는 주소를 요청해야 한다. <strong>삭제의 경우</strong>에는 <strong>/product_id/delete</strong> 형식의 주소를 지니고 있다. 
그 후, delete 함수 생성 및 삭제 요청 시 던져줄 <strong>product_id 라는 매개변수</strong>를 생성한다. <strong>product_id</strong> 란 /product/<strong>특정상품1개의 고유번호</strong>/delete 를 나타낸다.</li>
</ol>
</blockquote>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/fb91f69c-d1b8-400e-ab30-6360edbb27a4/image.png" alt="">= 해당 랜덤으로 생성되는 <strong>고유 id값</strong>을 나타내는 것이다.</p>
<blockquote>
<hr>
<ol start="2">
<li>delete_one 함수 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/b4cd83f2-dd3b-4adf-a3ca-9d1dd566e412/image.png" alt=""><strong>-&gt; controllers &gt; product.py![]</strong>(<a href="https://velog.velcdn.com/images/yohan-record/post/fa746002-f7fb-45e5-bc55-de498d7b9ded/image.png">https://velog.velcdn.com/images/yohan-record/post/fa746002-f7fb-45e5-bc55-de498d7b9ded/image.png</a>) <strong>-&gt; models &gt; product.py</strong>
= 하나의 <strong>products document</strong> 를 <strong>삭제</strong>해 주는데, <strong>어떤 document를 삭제해 줄것인가에 관한 부분을 작성</strong>해 주어야 한다.</li>
</ol>
</blockquote>
<p>즉, _id 가 objectID를 가지고 있는 document 를 삭제할 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/7469e0ae-cb09-4474-91b6-9499ae01f2dd/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>ex) 파란운동화를 삭제하고자 한다면 <strong>objectId</strong> 가 <strong>62e90f.....de 인것을 삭제하겠다</strong>는 것이다. </p>
<blockquote>
</blockquote>
<p>🔖 또한, objectId를 사용하기 위해서는 bson import 가 필요하다.
<strong>-&gt; from bson import ObjectId</strong></p>
<blockquote>
<hr>
<ol start="3">
<li>product_id 전달
<img src="https://velog.velcdn.com/images/yohan-record/post/9ee8c288-b9e1-4f13-bd09-ad77f3f8644e/image.png" alt="">= <strong>전달한 product_id</strong> 가 <strong>models &gt; product.py 의 id</strong>가 되고, <strong>objectId</strong>에 포함되고 <strong>_id가 objectID</strong>인 <strong>product document</strong> 하나를 삭제하게 된다.</li>
</ol>
<hr>
<ol start="4">
<li>삭제 요청 버튼 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/70a079d7-e407-49f8-8b09-8c1b1e8328ae/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/eefbfa6a-6b40-4216-96d5-6b1073e82127/image.png" alt=""> = <strong>고유 id값</strong>을 <strong>주소로 요청</strong>시킨 <strong>삭제기능이 포함된 버튼 하나</strong>를 생성시킨다.</li>
</ol>
<hr>
<ol start="5">
<li>삭제 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/bfc5d194-0597-4ecd-bffc-434936a45fa1/image.png" alt="">= 삭제하고자 하는 상품의 <strong>고유id값</strong>이 주소값에 출력되면서 return text 역시 출력되었다.
즉, <strong>삭제되었다는 의미</strong>이며 <strong>db상에서도 당연히 삭제가 완료</strong>되었다.</li>
</ol>
</blockquote>
<p>이로써 삭제기능까지 끝이 났다 !😎</p>
<p>실질적으로 돌아가는 logic을 파악하며 미리 한번 작업을 해보고, 포스팅을 하면서 두번 작업을 거치니 훨씬 더 깊게 이해가 가는 것 같다.</p>
<p>다음시간에는 상품 정보를 수정해보도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 9편 - list 커스텀 및 실제 값 부여]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-9%ED%8E%B8-list-%EC%BB%A4%EC%8A%A4%ED%85%80-%EB%B0%8F-%EC%8B%A4%EC%A0%9C-%EA%B0%92-%EB%B6%80%EC%97%AC</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-9%ED%8E%B8-list-%EC%BB%A4%EC%8A%A4%ED%85%80-%EB%B0%8F-%EC%8B%A4%EC%A0%9C-%EA%B0%92-%EB%B6%80%EC%97%AC</guid>
            <pubDate>Wed, 03 Aug 2022 12:55:24 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품-list">1. 상품 List</h2>
<p>✍ 이전 시간에서는 <strong>db에 저장된 document 정보들</strong>을 불러왔다면, 이번 시간에는 불러온 정보들을 <strong>실제 온라인스토어의 list 형태</strong>로 <strong>구조화</strong> 시킨 후 <strong>실제 값들을 넣어 보겠다.</strong> </p>
<blockquote>
<ol>
<li>html 구조 작성(bootstrap 활용)
= 이전 posting에서도 설명했듯이 필자가 <strong>현업에서 사용하는 fe 업무에 포함</strong>되어 있는 내용이고, <strong>따로 공부할 필요가 없다고 판단</strong>하여 <strong>도출된 결과물만 기록</strong>하도록 하겠다.
간단한 순서이지만, 표기해본다면 <strong>bootstrap demo들을 download</strong> 받은 후 <strong>include 경로</strong>만 맞춰주면 <strong>demo page와 동일</strong>하게 뿌려진다.
<img src="https://velog.velcdn.com/images/yohan-record/post/00a4d9fd-b58c-411d-995c-f75e5257d8f6/image.png" alt=""></li>
</ol>
<hr>
<ol start="2">
<li>반복문 작성
= <strong>같은 구조의 list</strong>가 뿌려지므로, 여러번 반복할 필요 없이 <strong>반복문</strong>으로 처리하여 <strong>db의 document 개수만큼</strong> 뿌린다.
ex) db 내부의 document 개수가 <strong>5개</strong>라면, <strong>5개가 동일한 구조</strong>로 뿌려진다.
<img src="https://velog.velcdn.com/images/yohan-record/post/15b2bddf-727d-4e27-8fc1-7878d559b792/image.png" alt=""><img src="https://velog.velcdn.com/images/yohan-record/post/9755469a-3f1e-4e34-914c-cd9c65b1d891/image.png" alt=""> 🔖 for문을 열어줬다면 <strong>반드시 닫는 코드도 필요</strong>하다. 빼먹지 않도록 주의 !!</li>
</ol>
<hr>
<ol start="3">
<li>db 실제 data값 뿌리기
<img src="https://velog.velcdn.com/images/yohan-record/post/cfb38f04-8968-49df-ac5f-af94ed9b7e0e/image.png" alt=""> = img를 upload 하고 난 후, 저장된 위치와 주소를 MongoDB에 저장해 두었는데, <strong>product 내부</strong>의 <strong>thumbnail_img, name, price 값</strong>을 호출시켜 실제 data를 출력시킨다.
<img src="https://velog.velcdn.com/images/yohan-record/post/3a4b533a-27de-4eec-9d81-e77083eb6130/image.png" alt=""></li>
</ol>
<hr>
<ol start="4">
<li>공통요소 include
= 각 page별로 html을 정의하는 <strong>기본 구조와 header들은 같기 때문</strong>에, 여러번 <strong>반복해서 재사용</strong>하기에는 <strong>효율이 떨어진다.</strong>
그러므로, <strong>include</strong>를 사용하여 <strong>한페이지에 공통된 내용을 넣어두고, 호출</strong>하는 방법으로 작업해 보겠다.
<img src="https://velog.velcdn.com/images/yohan-record/post/c17944ac-369f-47dd-aaea-0d4fc9783338/image.png" alt=""> = <strong>base.html file</strong>을 생성 후, 공통된 부분이 아닌 contents 영역 위치에 <strong>block content 요소</strong>를 하나 생성해 준다. 즉, <strong>각 페이지마다 바뀌는 contents 요소가 들어온다</strong>는 의미이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/57e52e48-9751-41bb-8688-86a1b2b1eac9/image.png" alt=""> = base.html (공통된 요소가 포함된 file) 을 <strong>extend</strong> 시켜준 후, <strong>각 page마다 바뀌는 contents 영역</strong>을 <strong>block content로 열고 닫은 후</strong> 그 안에 <strong>각 페이지의 고유 내용</strong>을 넣어주면 끝이다.</li>
</ol>
<hr>
<ol start="5">
<li>결과물
<img src="https://velog.velcdn.com/images/yohan-record/post/77500700-3cfe-4ea1-9480-2c7f6acd88f7/image.png" alt=""> = extend를 시킨 후, 상단 메뉴에 <strong>현재 생성된 file</strong>인 <strong>상품 리스트 및 상품등록 메뉴</strong>를 구성해두었다. 
작업물이 도출된 후, <strong>추후에</strong> 디테일하게 스타일 작업이 들어갈 것 같다. 😎</li>
</ol>
</blockquote>
<p>다음 시간에는 <strong>상품 리스트</strong>에서 <strong>상품을 삭제하는 API</strong>를 생성해 보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 8편 - 상품 list 조회]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-8%ED%8E%B8-%EC%83%81%ED%92%88-list-%EC%A1%B0%ED%9A%8C</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-8%ED%8E%B8-%EC%83%81%ED%92%88-list-%EC%A1%B0%ED%9A%8C</guid>
            <pubDate>Wed, 03 Aug 2022 11:50:59 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품조회">1. 상품조회</h2>
<p>✍ 상품등록 방식과 유사하다. flask 에서 주소로 <strong>products/list(get)</strong> 접속 할 때, <strong>products.html</strong> file을 전달시킬 것이다.</p>
<blockquote>
<ol>
<li>API 생성 <img src="https://velog.velcdn.com/images/yohan-record/post/f6daf52b-01c5-4c7e-9ae5-462f35d7662e/image.png" alt=""> = <strong>product route 의 주소</strong>는 <strong>/list</strong>(get 방식은 default 이므로 표기안함) 로 설정하였고, 함수명은 <strong>get_products</strong> 로 정의하였다.</li>
</ol>
<p>즉, <strong>list 주소를 입력</strong> 시 <strong>get_products 함수가 호출</strong> 되고, <strong>상품 리스트를 땡겨와야 한다.</strong></p>
</blockquote>
<p>말보다는 역시 설명이므로 그림으로 <strong>흘러가는 logic</strong> 을 구상해 보겠다. <img src="https://velog.velcdn.com/images/yohan-record/post/5d8637ee-36f8-45c0-b7d2-54defb69f1ce/image.png" alt="">... 사실 나만 알아볼 거 같긴 하다 ^^;; 😅
간단하게 보자면, <strong>db &gt; products &gt; collection &gt; document(상품명, 가격, 이미지 등등...)</strong> 을 뽑아와서 <strong>list에 뿌려준다</strong>고 생각하면 될 것 같다.</p>
<blockquote>
</blockquote>
<p>🔖 <em>Product collection 안에 있는 내용을 작성</em>할 때는, <em>models &gt; product file</em>에서 작성해 준다.</p>
<blockquote>
<hr>
<ol start="2">
<li>staticmethod 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/4e9f3b9b-e028-47b7-95d0-6ed904ce645b/image.png" alt=""> = product collection 안에 있는 <strong>모든 document 들</strong>을 <strong>find()</strong> 로 가져온다.
<img src="https://velog.velcdn.com/images/yohan-record/post/27453a6d-af01-4fe8-8e23-04b3d7269647/image.png" alt=""> = 그 후, find 함수를 작성시켜준다.</li>
</ol>
<hr>
<ol start="3">
<li>상품 list 정보 출력을 위한 html file 생성( templates &gt; products.py)
<img src="https://velog.velcdn.com/images/yohan-record/post/0b551423-d89c-4c93-a1f3-749a8debeaf0/image.png" alt=""> = <strong>blueprint로 products 를 mapping</strong> 해 두었으므로, <strong>/products/list 주소 호출</strong> 시 <strong>products.html file</strong>의 내용이 보여지게 된다.</li>
</ol>
<hr>
<ol start="4">
<li>product 정보 출력
<img src="https://velog.velcdn.com/images/yohan-record/post/6660372a-4668-461a-88a5-5f9469b15c50/image.png" alt=""> = <strong>product1</strong> 변수에 <strong>products</strong>(DB 안 documents 들의 내용을 담은 변수) 를 <strong>담아준다.</strong>
<img src="https://velog.velcdn.com/images/yohan-record/post/e4846ee4-0019-4151-9bf9-d9195196812d/image.png" alt=""> = html file에서 <strong>products에 있는 배열 요소들</strong>을 개수만큼 for문을 돌려서 하나하나 출력을 시켜준다.
<img src="https://velog.velcdn.com/images/yohan-record/post/ee4c1c2d-07f9-4857-a8f3-7f5a41833e9d/image.png" alt=""> = document 요소 하나하나가 출력이 되었다.</li>
</ol>
</blockquote>
<p>결과물과 같이 <strong>db에 저장된 list들</strong>을 출력시켜주었다.</p>
<p>다음시간에는 실제 store처럼 보이도록 <strong>html 구조 및 css 작업</strong>을 통하여 list 처럼 보이게 만들어 보겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 7편 - web browser 상품등록]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-7%ED%8E%B8-web-browser-%EC%83%81%ED%92%88%EB%93%B1%EB%A1%9D</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-7%ED%8E%B8-web-browser-%EC%83%81%ED%92%88%EB%93%B1%EB%A1%9D</guid>
            <pubDate>Tue, 02 Aug 2022 12:54:32 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-상품등록">1. 상품등록</h2>
<p>✍ form &gt; input 값에 맞게 상품이름, 가격, 설명, 이미지 등 첨부 후 등록버튼을 클릭 시 값이 전송되는 logic으로 구성되어있다.</p>
<blockquote>
<ol>
<li>API 생성
<img src="https://velog.velcdn.com/images/yohan-record/post/1ae1f6f3-c4fd-4f61-b044-240dd88934bb/image.png" alt=""> = get 방식(default)으로 <strong>form을 호출</strong> 시 등록 화면이 보이도록 <strong>호출하는 API</strong>를 생성하는 것이다.</li>
</ol>
</blockquote>
<p>  즉, <strong>/form 주소</strong>로 <strong>flask 요청</strong>을 하게 되면, <strong>product_form.html file을 반환</strong>해 주겠다는 코드이다.</p>
<blockquote>
</blockquote>
<p> 🔖 render template <strong>사용</strong>을 위해서, <strong>import</strong> 필요함
 -&gt; <strong>from flask import request, render_template</strong></p>
<blockquote>
<hr>
<ol start="2">
<li>templates folder 생성 및 &gt; product_form.html 생성
= browser 상으로 확인을 해보기에 앞서, <strong>/form</strong>을 mapping 시켜두었지만, 앞전에 <strong>blueprint로 주소창 앞에 /products</strong> 를 잡아두었으므로, 실질적인 주소는 <strong>&quot;/products/form&quot;</strong> 을 입력 시 호출 될 것이다.</li>
</ol>
<hr>
<ol start="3">
<li>html 태그 작성
<img src="https://velog.velcdn.com/images/yohan-record/post/97e8e1f2-38a7-4eb1-952f-9fc1f2c70881/image.png" alt="">= 상품 등록 버튼을 <strong>submit으로 전송</strong> 시, <strong>/products/regist 주소값으로 등록을 요청한 값이 전달</strong>된다.</li>
</ol>
</blockquote>
<p>  값이 주소창에 <strong>노출되는 것 보다는 privacy 한 것</strong>이 나으므로 <strong>post값</strong>으로 전송하며 <strong>upload(img) 입력값</strong>도 포함되어있으므로 <strong>multipart</strong> 값을 추가한다.</p>
<blockquote>
<hr>
<ol start="4">
<li>전송 값 확인(error - 각 input에 name 값이 없을 경우)
🧨 3번 이미지에서는 <strong>각 input마다 name값</strong>이 포함되어 있어 정상적으로 값이 전송되고, db에 저장되지만 <strong>name값이 없을 경우를 가정</strong>하여 테스트 해보았다.🧨
<img src="https://velog.velcdn.com/images/yohan-record/post/910ca09b-46f2-4cbc-a196-a787c2104b14/image.png" alt=""> = nonetype 및 filename error가 발생한다. product controller에서 filename이 존재하는데, upload 시 filename이 없다는 error 인 것이다.</li>
</ol>
<p>즉, <strong>값이 전달되지 않았다는 것</strong>이다. 각 입력값이 어떠한 변수값을 가지고 전달이 되어야하는데, <strong>변수가 저장되지 않아 전달받을 때 아무것도 없다</strong>고 <strong>인식</strong>을 하는 것이다.</p>
<p>request.form으로 요청을 받을 때, 해당 name을 찾아서 전송받은 값을 저장할 수 있게 되는 것이다.
<img src="https://velog.velcdn.com/images/yohan-record/post/b795927e-cbf9-4698-994f-a608cbb3ce41/image.png" alt=""></p>
<hr>
<ol start="5">
<li>전송값 입력 및 확인(success)
= name값을 각각 부여한 후, db에 저장하기 위해 data 값을 전송 시 저장되는 것까지 확인할 수 있다.
<img src="https://velog.velcdn.com/images/yohan-record/post/8ac422d3-b154-429b-9d36-b2b8c4dee5f4/image.png" alt="">
<img src="https://velog.velcdn.com/images/yohan-record/post/04de77d8-07b8-4b9f-838a-3dcbdbf08c37/image.png" alt=""></li>
</ol>
</blockquote>
<p>⌛ 현재 등록 폼은 <strong>아무런 스타일도 잡혀있지 않는 html 구조</strong>이다.</p>
<p>이 폼을 css(아마 bootstrap을 사용할 예정) 로 스타일 작업을 해주어야 하는데, <strong>현업에 포함되어있는 작업내용이라 따로 공부할 필요가 없다고 판단했다.</strong></p>
<p>별도의 과정설명 없이 작업 후 결과물만 보여주는 것으로 대체하겠다.⌛ </p>
<h2 id="2-결과">2. 결과</h2>
<p><img src="https://velog.velcdn.com/images/yohan-record/post/6db0b57a-dbb6-4bfb-89c1-0261be96a3ba/image.png" alt="">= 보이는 바와 같이 깔끔하게 구현해 내었다. bootstrap을 이용하여 작업하였는데, 나는 bootstrap을 현업에도 사용하지 않고, 그다지 선호하지 않는다. </p>
<p>단순한 프로젝트인 경우 간단하게 보이는 바와 같이 클래스만 땡겨서 스타일을 구축해 낼 수 있지만..</p>
<blockquote>
<ol>
<li>실질적인 프로젝트에서의 시안은 boostrap을 활용하기에 어렵다.</li>
<li>기존 초기화 코드인 reset과 겹치는 class가 많다.</li>
</ol>
</blockquote>
<p>장점도 물론 뛰어나지만, 프로젝트를 진행하는데에 있어서 단점이 더 많다고 판단하여 css 및 sass를 활용하여 component를 구축하고 module 별로 땡겨쓰는 방식으로 작업을 하고 있다.</p>
<p>이와 같이 상품 등록을 browser 상에서 확인해 내었고,
다음 과정은 상품등록으로 저장한 상품을 list page에 뿌려보도록 하겠다.</p>
<p>이제 점점 재밌어지고 있다!!!!!😎😎</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🦁 Python Online Store 만들기 6편 - 상품 이미지 upload]]></title>
            <link>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-6%ED%8E%B8-%EC%83%81%ED%92%88-%EC%9D%B4%EB%AF%B8%EC%A7%80-upload</link>
            <guid>https://velog.io/@yohan-record/Python-Online-Store-%EB%A7%8C%EB%93%A4%EA%B8%B0-6%ED%8E%B8-%EC%83%81%ED%92%88-%EC%9D%B4%EB%AF%B8%EC%A7%80-upload</guid>
            <pubDate>Tue, 02 Aug 2022 11:17:21 GMT</pubDate>
            <description><![CDATA[<p>🎈** Front End Developer 의 Back End 도전기 !** 🎈</p>
<p>이 글은 <a href="https://projectlion.io/">PROJECT LION : 호코치 강사님의 강의</a>를 들으며 참고한 글입니다.</p>
<p>작업 중, 개발과정 정리 및 issue가 되었던 부분들을 공유 및 기록하고자 작성하게 되었습니다.</p>
<h2 id="1-img-upload">1. img upload</h2>
<p>✍ 이전 시간에는 판매하고자 하는 <strong>상품의 고유 값 및 정보들의 값</strong>을 <strong>db</strong>에 저장하였다.</p>
<p>추가적으로 list에 뿌려질 thumbnail img 및 view page의 img 도 파일 경로를 생성한 후 지정된 filename으로 저장하여 값을 넘겨보도록 하겠다.</p>
<blockquote>
<ol>
<li><p>request file 경로 생성(thumbnail 및 detail img)
 <img src="https://velog.velcdn.com/images/yohan-record/post/98e3c5c4-fcd1-4461-9b2b-527c4460dce5/image.png" alt="">= 해당 <strong>img file을 upload</strong> 하게 되면, <strong>request.files</strong> 라는 곳에 thumbnail_img 및 detail_img 라는 <strong>file의 정보</strong>를 얻을 수 있다. </p>
<p> file 정보의 경우 <strong>어딘가에 저장</strong> 해 주어야 하는데, file은 <strong>text가 아닌 말 그대로 file 형태</strong>이기 때문에 python file 과 같은 <strong>file 형태로 저장해 주어야 한다.</strong></p>
</li>
</ol>
<hr>
<ol start="2">
<li>img_file upload 위한 함수 생성 
<img src="https://velog.velcdn.com/images/yohan-record/post/5a5feb2e-c63e-437a-a396-42d2aaf81367/image.png" alt="">= 각 코드의 흐름에 맞게 순서대로 주석처리 하였지만 다시한번 복습할 겸 순서를 나열하며 코드를 재작성 해보겠다.</li>
</ol>
<p>🧸 <strong>함수 내부 순서</strong> 🧸
  2-1. upload 시킨 날짜를 확인하기 위해, timestamp 함수 사용
  2-2. 생성된 file 이름에는 생성한 날짜와 이름을 추가한다.
  2-3. upload 시키고자 하는 path 설정
  2-4. directory 존재 유무를 파악하여 해당 directory에 path 및 filename upload
  2-5. path 경로에 file save
  2-6. 저장된 path 경로 &gt; img file mongoDB upload</p>
<hr>
<ol start="3">
<li>upload file 함수 호출 및 img 값 db전달
<img src="https://velog.velcdn.com/images/yohan-record/post/98250c85-f3ed-4889-b61f-d7d831d9ea15/image.png" alt=""> = upload_file 함수 호출 및 <strong>요청</strong>한 img 값을 <strong>thumnail_img_url 및 detail_img_url 변수</strong>에 저장 후, db 에 전달하기 위해 insert_one 내부에 <strong>값을 전송</strong>해준다.</li>
</ol>
<hr>
<ol start="4">
<li>요청 후 전달받은 값 db 전송
<img src="https://velog.velcdn.com/images/yohan-record/post/e97f61fc-cabc-4384-98cb-0b80158fca76/image.png" alt=""> = db에 보내줄 값을 받아서, insert 시켜준다(user값은 임의로 admin으로 세팅했으며, 생성날짜 및 수정날짜는 filename을 저장할 때 처럼 timestamp 값을 정수 type으로 생성하여 db에 담아주었다.)</li>
</ol>
<hr>
<ol start="5">
<li>datetime, secure_filename, os 불러오기
<img src="https://velog.velcdn.com/images/yohan-record/post/eba14f78-c071-4fdf-8351-43eee75b4dc6/image.png" alt=""> = <strong>models &gt; product.py file</strong>도 <strong>datetime</strong> 을 <strong>사용</strong>했으므로, 동일하게 <strong>datetime import 필요</strong></li>
</ol>
<hr>
<ol start="6">
<li>upload 테스트
<img src="https://velog.velcdn.com/images/yohan-record/post/3ebd20bb-afb3-40dd-a6ba-9202bfcc1a01/image.png" alt=""> = Insomnia 접속 후, file 형태로 thumbnail img 및 detail img 첨부 후 전송</li>
</ol>
<hr>
<ol start="7">
<li>static/uploads folder <strong>생성 확인</strong>
<img src="https://velog.velcdn.com/images/yohan-record/post/91d0b099-9feb-4a11-b7fa-e2e2464e17e9/image.png" alt=""></li>
</ol>
<hr>
<ol start="8">
<li>MongoDB 전송 값 확인
<img src="https://velog.velcdn.com/images/yohan-record/post/c5c978d5-c65c-458f-9b70-968a69aab318/image.png" alt=""></li>
</ol>
</blockquote>
<p>이로써 <strong>img file</strong>이 <strong>db</strong>에 정상적으로 저장 된 것을 확인할 수 있다 😎</p>
<p><strong>상품등록 API에 대한 구현</strong>을 완료하였다!</p>
<p>현업에서는 <strong>fe 업무</strong>만 수행하고 있어, 실질적으로 값을 저장하고 넘기는 작업은 처리해 보지 못했는데, 실제로 코드를 작성하고 값을 넘기는 작업을 수행해보니 재밌는 것 같다. (<del>아직 코드는 손쉽게 작성하지는 못할 것 같다 😂</del>)</p>
<p>다음시간에는 <strong>상품등록 page</strong>를 구현하여 실제 <strong>web browser에서 등록이 가능</strong>하도록 해보겠다.</p>
]]></description>
        </item>
    </channel>
</rss>