Class-based view 상품 상세 보기 및 주문

Codren·2021년 5월 14일
0

Django 실전

목록 보기
4/12

Section 1. 상품 상세 보기

1. Class-based View 생성

  • DetialView 상속 (from django.views.generic import DetailView)
  • queryset 에서 URL 을 통해 들어온 pk 값을 갖는 행을 출력함



2. URL 파싱

  • path('product/<int:pk>/', ProductDetail.as_view()) 추가
  • 상품의 pk 값을 URL 로 보내면 view 에서 해당 pk 값을 갖는 상품만을 출력 (django 자동)



3. Template 생성

{ product.description|safe}}	# safe : html 태그 및 base 64 이미지 파일 변환



4. 상품 상세 보기 화면




Section 2. 상품 주문

1. 상품 주문 원리

  • 상품 상세 보기에서 수량을 지정하고 주문하기 버튼을 누르는 방식
  • 상품 상세 보기에서 주문하는 user / product / quantity 값이 form을 통해 POST 요청
  • 상품을 보는 user 와 해당 상품 product 의 값이 자동으로 POST 요청
  • 상품 상세 보기 GET 방식과 상품 주문 POST 방식을 나누어서 처리



2. form 생성

  • 상품 주문 시에는 수량만 지정하고 user 와 product의 정보는 자동으로 보내지기 때문에 product 의 form 요소를 HiddenInput 형식으로 지정하고 id 값이기 때문에 IntegerField 지정
  • user 의 session 값을 얻기 위해서 __init__ 생성자를 통해 form 이 생성될 때 request 를 전달 받음
  • 트랜잭션을 통해서 order 를 생성하고 주문된 수량만큼 해당 product 의 재고에서 차감
  • 수량을 지정하지 않거나 로그인 상태가 아니라면 상세보기를 다시 출력하도록 product 값 저장 해 놓음
def __init__(self,request, *args, **kwargs):  	# form이 생성될 때 request 값 또한 입력으로 받음
        super().__init__(*args,**kwargs)        # 원래의 __init__ 수행하고
        self.request = request 			# 입력으로 받은 request를 form의 변수로 저장
        
user = self.request.session.get('user')      	# form의 변수로 request를 저장했으니 self로 접근  (from django.db import transaction)

with transaction.atomic(): 			# 해당 indent 부분 트랜잭션 처리





3. Class-based View 생성

  • form_invalid() - form 에 대한 유효성 검사가 실패할 때 수행되는 함수(form 에 error 존재)
  • 수량을 지정하지 않거나 로그인 상태가 아니라면 해당 상품 상세보기를 다시 출력
  • get_form_kwargs() - POST 형식일 때 입력된 form 의 값들을 전달하는 함수
  • 자동으로 입력된 product 의 정보와 사용자가 직접 지정한 수량에 request 값을 추가함
def form_invalid(self, form):		# 원래의 invalide 기능은 template_name 에 지정된 template 에 error 정보 렌더링
form.data.get('product')		# form.product 로도 접근 가능

get_form_kwargs(self, **kwargs):    	# kwargs 매개변수 생략 가능 (부모의 함수에도 존재 X)





4. 상품 상세 보기 Template 수정

  • form 요소 출력
  • product 는 HiddenInput 이므로 label 을 표시하지않고 사용자가 값을 지정할 수 없기 때문에 자동으로 해당 product 의 정보가 넘어가도록 value 속성에 {{product.id}} 지정
  • 주문하기 버튼을 누르면 해당 form 값들을 가지고 /order/create/ 로 요청




5. 상품 상세보기 View 수정

  • 상품 상세보기 View 는 DetailView 이므로 화면에 form 또한 출력하기 위해서 Template 으로 보내지는 data 에 form 을 추가해서 보내야 함
  • get_context_data() - template 에 data 를 보내는 함수
  • 상품 주문에서 form 이 생성될 때 __init__() 에서 request 를 입력 받았으므로 에러 방지를 위해서 똑같이 request 를 넘겨줌
from order.forms import RegisterForm as OrderForm  	# Product 의 RegisterForm 과의 구별을 위해
context['form'] = OrderForm(self.request)  		# OrderForm 으로 앨리어싱



6. URL 파싱

  • path('order/create/', OrderCreate.as_view()) 추가



7. 수정된 상품 상세 보기 화면




Section 3. 상품 주문 처리 로직

1. 상품 상세 보기 화면

  • 개발자 도구로 확인하면 자동으로 product form 요소 value 값에 product 값 지정됨

  • 수량 10개 지정 후 주문하기 버튼 누르기




2. GET vs POST 방식

  • 둘 의 차이점을 확인하기 위해 form 이 생성될 때 값을 확인하도록 print 로 각각 출력

  • GET 방식 (상세보기 화면 요청)
    - request 값 존재
    - args, kwargs 값 존재 X

  • POST 방식 (주문하기 요청)
    - request 값 존재
    - args, kwargs 값 존재




3. get_form_kwargs

  • POST 방식일 때 __init__ 으로 보내지는 값들 확인을 위해 print


  • 결과
    - 'data' : <QueryDict\:product,quqntity> form 에 입력된 값들
    - 'request':<WSGIRequest> 추가한 request 값
    - 따라서 kw로 request 를 보냈다고 해서 form 에서 cleaned.data.get() 으로 접근 불가능




4. 주문 결과

  • 자동으로 재고가 90개로 변경됨

0개의 댓글