Server/Django project 1 - shopping mall

11. Django order app 상품 주문하기 (1)

개발자킹콩 2020. 10. 6. 17:28

이번 파트는 많은 내용을 담고 있기에 2편으로 나누어 진행하였다.

지금까지 만든 shopuser(유저), product(물건) app을 구현하였다.

이제 해당 유저가 이 쇼핑몰에서 물건을 사게 되는 경우 이루어지는 기능을 구현한다.

이번엔 기능 별로 목차를 나눌 것이다. 파일을 여기저기 왔다갔다 할꺼니깐 잘따라와!!

가즈아!!!!!!!!!!!!!!!!!!!!!!!!!

 

 

목차 : 

1. forms.py

2. views.py

3. FormView( order/views.py ) , urls.py

4. template 수정 ( product_detail.html )

5. 문제점

 

 

 

 

 


1. forms.py

 

주문하기의 경우 주문하는 페이지를 별도로 만들지 말고,

상품 상세페이지(product_detail.html)에서 수량을 form으로 입력받아 주문하도록 만들어보자

일단 상세보기에서 수량과 주문버튼을 생성하자

product_detail.html 에서 수량을 입력받는 form을 생성하고

"주문" 버튼을 누르면 form을 전달하도록 한다. FormView를 활용하자.

기능의 경우 비슷한 구조이기에 이전 product에서 만들었던 forms.py를 복사하여

order app에 수정하여 추가하도록 하자

 

 

form으로 입력 받을 데이터를 생각해보자. 

우선 사용자가 제품을 특정 수량만큼 주문하는 것에 대한 기능이 필요한 것이다.

 

order / forms.py

 

  • 유저의 경우 현재 로그인이 된 상태라면 session에 정보가 있기에, 주문자의 id를 입력받을 필요는 없다.
  • 수량의 경우 기재 되어야할 정보이기 때문에 form으로 데이터를 받아온다.
  • 상품의 경우 id를 들고 올 것이기에 IntegerField로 설정하고, 현재 상품에서 해당 제품을 주문하는 것이기에 form이 필요없다. 따라서 HideenInput으로 widget을 설정한다.

 

 

 

 

이제 product_detail.html 에 지정한 form과 주문하기 버튼을 입력하고,

action을 통해 링크("/order/create/")를 지정하고 form에 대한 정보를 해당 url로 보낸다. 

  

product_detail.html

 

 

 

form이 나오지도 않는구만..

우리는 아직 template과 form을 연결해주지 않았다.

어떻게 연결되는지 큰 그림을 머리속으로 그린 다음 가보자잉!!!!

우리가 할 일은 form문을 template(.html)에서 인지할 수 있도록 views.py를 수정할 것이다.

 

 

그런데 우리는 order app에서는 template를 만들지 않았는데 view를 만들 필요가 있을까?

엄따!!!!

그래서 product/views.py의 class ProductDetail 안에서 기존에 전달한 정보에

추가적인 정보를 전달을 하는 방법으로 해당 form구현을 해보겠다

 

 

 

 


 

 

 

 

2. views.py

 

이제 views.py를 작업할 것이다. 

위의 설명과 같이 order/views.py 가 아닌 product/views.py를 수정할 것이고

주문은 product_detail.html에서 이루어 지기에 해당 클래스 안에서 정보전달 코드를 작성할 것이다.

 

product / views.py

 

보면 "주문하기"에서 수량에 해당하는 form정보를 전달하는 코드가 없다. 

내가 여기 DetailView에 form을 전달해줘야 그 변수를 갖고 form을 만든다.

 

내가 원하는 데이터를 넣을 수 있도록 함수를 제공한다.

--> get_context_data(self, **kwargs)

 

 

 

super를 통해서 기존에 호출되는 함수를 먼저 호출하는데,

먼저 DetailView가 자동으로 전달해주는 데이터( Detail )를 먼저 만들고 나서 

거기에 내가 만든 데이터( Form )를 추가하는 방식이다.

--> context['form'] 에다가 우리가 만든 OrderForm을 넣고 return 하여 전달을 하면 된다.

 

 

product / views.py

 

이렇게 되면 먼저 생성된 context 안에 'form' 이라는 변수로 하나의 데이터를 추가했고,

반환하면 다음과 같이 product_detail.html에서 주문기능에서 form문이 생성된다.

 

 

 

 

 

 

 

 


 

 

 

 

3. FormView( order/views.py ) , urls.py

 

이제 해당 url에 맞는 FormView가 있어야 한다.

url에 접근하면 연결되어야 할 view의 class가 있어야 하잖아~

이 FormView는 order/views.py에 만들면 되겠지!!

 

 

order / views.py

해당 클래스에서는 해당 기능을 보여줄 templates를 만들지 않았기에

template_name를 지정하지 않아도 된다.

 

 

urls.py

 

 

 

 

 


 

 

 

 

 

4. template 수정 ( product_detail.html )

정상적으로 form이 생성되었다.

이제 template에 추가할 건 추가하고, 삭제할 건 삭제하자!

  • OrderForm을 살펴보면 product에 해당하는 label이 표시된것을 볼수있다. 해당 form은 HiddenInput이기에 표시되지 않도록 하자.
  • product의 value를 설정하기 (product detail에서 주문하면 지금이 상품을 주문하는 것이다.
  • form 이기에 보안을 위한 {% csrf_token %}
  • 재고에 해당하는 데이터를 추가하자

 

 

 

● 해당 label을 표시하는 코드에서 조건을 두어 product는 표시하지 않도록 설정한다.

    그렇게 되면 아래와 같이 구현된다.

 

product_detail.html

 

 

 

 

 

 

● product의 경우 value값이 자동으로 들어가게 된다.

   해당 form에 수량을 적으면 해당 product를 구매한다는 것을 설정한 것이다.

 

 

 

브라우져에서 개발자옵션

 

 

 

● 값을 입력받는 form의 경우 내부의 코드에 영향을 줄 수 있기에 보안상으로 문제가 존재한다.

   (시스템소프트웨어 과목에서 배운 canary value와 유사하다고 이해하면 쉽다.)

   모른다면! 우리가 입력받는 값 앞에 보안장치를 생성하는 것과 같다.

   form의 경우  {% csrf_token %} 를 삽입함을 잊지말자!!

 

 

 

 

 

 

 

● 주문을 할 경우 재고의 상태를 바로 확인하기 위해 다음과 같이 재고 데이터를 추가하자

 

 

 


 

5. 문제점

 

 

이제 기본적인 연결은 완성 되었다.

이제 주문의 기능 자체를 구현할 차례이다.

"수량"을 입력하고 "주문하기"를 누르면 해당 수량만큼 재고가 줄어들고,

"주문"에 해당하는 데이터 또한 정상적으로 들어와야 한다.

 

 

order / forms.py

 

앞서 설명했듯이 상품을 주문한다는 것은,

해당 상품임을 인지하고 입력받은 수량만큼 주문을 하는 것인데,

주문하는 상대는 현재 로그인 되어있는 USER이다. 즉, session을 가져와야한다.

session을 가져오려면 form안에서 request.session에 접근할 수 있어야 하지만,

현재는 request로 설정된 것이 없다.

즉 해당 OrderForm에서는 request.session에 접근할 수 없다.

다음 페이지에서 session에 접근 가능하도록 form을 변경할 것이다.

 

 

 

 

 

여기까지!! 오늘도 감코!!