{% extends "base.html" %}
{% load humanize%}
{% block contents %}
<div class="row mt-5">
<div class="col-12">
<div class="card" style="width: 100%;">
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<form method="POST" action="/order/create/">
{% for field in form %}
<div class="form-group">
{% ifnotequal field.name 'product' %}
<label for="{{ field.id_for_label}}">{{field.label}}</label>
{% endifnotequal %}
<input type="{{field.field.widget.input_type}}" class="form-control"
id="{{ field.id_for_label}}" placeholder="{{field.label}}" name="{{field.name}}" />
</div>
{% if field.errors %}
<span style="color: red;">{{ field.errors }}</span>
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-primary">주문하기</button>
</form>
</li>
<li class="list-group-item">가격 : {{ product.price|intcomma }} 원</li>
<li class="list-group-item">등록날짜 : {{ product.register_date|date:'Y-m-d H:i' }}</li>
<!-- description은 태그이기 때문에 필터로 |safe를 해주면 html 태그로 만들어준다! -->
<li class="list-group-item">{{ product.description|safe }}</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<a href="/product/">목록보기</a>
</div>
</div>
</div>
{% endblock %}
from django import forms
from .models import Order
class RegisterForm(forms.Form):
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
from django.shortcuts import render
from django.views.generic import ListView, DetailView
from django.views.generic.edit import FormView
from .models import Product
from .forms import RegisterForm
from order.forms import RegisterForm as OrderForm
# Create your views here.
class ProductList(ListView):
model = Product
template_name = 'product.html'
# object_list로 사용하기 싫으면 context_object_name으로 변경 가능
context_object_name = 'product_list'
class ProductCreate(FormView):
template_name = 'register_product.html'
form_class = RegisterForm
success_url = '/product/'
class ProductDetail(DetailView):
template_name = 'product_detail.html'
# 어떤 모델이 아닌 쿼리셋을 지정
# 필터를 통해서 보여질지 말지도 결정할 수 있다
queryset = Product.objects.all()
# template에서 사용할 변수명 지정
context_object_name = 'product'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = OrderForm()
return context
from django.shortcuts import render
from .forms import RegisterForm
from django.views.generic.edit import FormView
# Create your views here.
class OrderCreate(FormView):
# 화면은 따로 구연할 필요 없기 때문에 template_name = 은 생략
form_class = RegisterForm
success_url = '/product/'
from django.contrib import admin
from django.urls import path
from fcuser.views import index, RegisterView, LoginiView
from product.views import ProductList, ProductCreate, ProductDetail
from order.views import OrderCreate
urlpatterns = [
path('admin/', admin.site.urls),
path('', index),
# class는 .as_view()를 입력!
path('register/', RegisterView.as_view()),
path('login/', LoginiView.as_view()),
path('product/', ProductList.as_view()),
path('product/create/', ProductCreate.as_view()),
# 상세보기 페이지는 주소에 어떤 상품인지 나타낼수 있어야한다!
# url에 지정을 할 수 있는데, detailView에서 기본적으로 pk라는 값을 사용
# <int:pk> 숫자형으로 받고 받아온 숫자는 pk라는 변수로 사용
path('product/<int:pk>/', ProductDetail.as_view()),
path('order/create/', OrderCreate.as_view()),
]
{% extends "base.html" %}
{% load humanize%}
{% block contents %}
<div class="row mt-5">
<div class="col-12">
<div class="card" style="width: 100%;">
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<form method="POST" action="/order/create/">
{% for field in form %}
<div class="form-group">
{% ifnotequal field.name 'product' %}
<label for="{{ field.id_for_label}}">{{field.label}}</label>
{% endifnotequal %}
<input type="{{field.field.widget.input_type}}" class="form-control"
id="{{ field.id_for_label}}" placeholder="{{field.label}}" name="{{field.name}}"
value="{% ifequal field.name 'product' %}{{ product.id }}{% endifequal %}" />
</div>
{% if field.errors %}
<span style="color: red;">{{ field.errors }}</span>
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-primary">주문하기</button>
</form>
</li>
<li class="list-group-item">가격 : {{ product.price|intcomma }} 원</li>
<li class="list-group-item">등록날짜 : {{ product.register_date|date:'Y-m-d H:i' }}</li>
<!-- description은 태그이기 때문에 필터로 |safe를 해주면 html 태그로 만들어준다! -->
<li class="list-group-item">{{ product.description|safe }}</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<a href="/product/">목록보기</a>
</div>
</div>
</div>
{% endblock %}
from django import forms
from .models import Order
class RegisterForm(forms.Form):
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
product = cleaned_data.get('product')
# 사용자 정보!, requst.session에 접근이 필요!
from django import forms
from .models import Order
from product.models import Product
from fcuser.models import Fcuser
class RegisterForm(forms.Form):
# 생성자함수
# requst에 전달하기 위해서 생성자 함수를 생성
# product views의 productDetaile에서 form을 생성하는 부분이 있습니다!
# 그리고 order의 views.py에서 request를 처리한다
def __init__(self, request, *args, **kwargs):
# 기존에 있던 생성자를 사용할 수 있도록 super()에서 불러온다!
super().__init__(*args, **kwargs)
self.request = request
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
product = cleaned_data.get('product')
# 사용자 정보!, requst.session에 접근이 필요!
print(self.request.session)
{% extends "base.html" %}
{% load humanize%}
{% block contents %}
<div class="row mt-5">
<div class="col-12">
<div class="card" style="width: 100%;">
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<form method="POST" action="/order/create/">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{% ifnotequal field.name 'product' %}
<label for="{{ field.id_for_label}}">{{field.label}}</label>
{% endifnotequal %}
<input type="{{field.field.widget.input_type}}" class="form-control"
id="{{ field.id_for_label}}" placeholder="{{field.label}}" name="{{field.name}}"
value="{% ifequal field.name 'product' %}{{ product.id }}{% endifequal %}" />
</div>
{% if field.errors %}
<span style="color: red;">{{ field.errors }}</span>
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-primary">주문하기</button>
</form>
</li>
<li class="list-group-item">가격 : {{ product.price|intcomma }} 원</li>
<li class="list-group-item">등록날짜 : {{ product.register_date|date:'Y-m-d H:i' }}</li>
<!-- description은 태그이기 때문에 필터로 |safe를 해주면 html 태그로 만들어준다! -->
<li class="list-group-item">{{ product.description|safe }}</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<a href="/product/">목록보기</a>
</div>
</div>
</div>
{% endblock %}
from django.shortcuts import render, redirect
from .forms import RegisterForm
from django.views.generic.edit import FormView
# Create your views here.
class OrderCreate(FormView):
# 화면은 따로 구연할 필요 없기 때문에 template_name = 은 생략
form_class = RegisterForm
success_url = '/product/'
# form을 생성할 때 어떤 인자값을 전달해서 만들건지를 결정하는 함수
# formview안에서도request를 전달할 수 있게 해주어야 한다!
def get_form_kwargs(self, **kwargs):
kw = super().get_form_kwargs(**kwargs)
kw.update({
# 기존에 있던 인자 값에다가 request를 포함하겠다!
'request': self.request
})
return kw
from django import forms
from .models import Order
from product.models import Product
from fcuser.models import Fcuser
class RegisterForm(forms.Form):
# 생성자함수
# requst에 전달하기 위해서 생성자 함수를 생성
# product views의 productDetaile에서 form을 생성하는 부분이 있습니다!
# 그리고 order의 views.py에서 request를 처리한다
def __init__(self, request, *args, **kwargs):
# 기존에 있던 생성자를 사용할 수 있도록 super()에서 불러온다!
super().__init__(*args, **kwargs)
self.request = request
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
product = cleaned_data.get('product')
# 사용자 정보!, requst.session에 접근이 필요!
print(self.request.session)
from django import forms
from .models import Order
from product.models import Product
from fcuser.models import Fcuser
class RegisterForm(forms.Form):
# 생성자함수
# requst에 전달하기 위해서 생성자 함수를 생성
# product views의 productDetaile에서 form을 생성하는 부분이 있습니다!
# 그리고 order의 views.py에서 request를 처리한다
def __init__(self, request, *args, **kwargs):
# 기존에 있던 생성자를 사용할 수 있도록 super()에서 불러온다!
super().__init__(*args, **kwargs)
self.request = request
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
product = cleaned_data.get('product')
# 사용자 정보!, requst.session에 접근이 필요!
fcuser = self.request.session.get('user')
if quantity and product and fcuser:
order = Order(
quantity=quantity,
product=Product.objects.get(pk=product),
fcuser=Fcuser.objects.get(email=fcuser)
)
order.save()
# 실패했을 경우에
# 템플릿 이름이 지정되지 않아 이대로면 오류가 난다
# 주문하기 페이지를 따로 만들지 않기 때문에 템플릿을 만들필요는 없다!
# Order의 views에 함수를 만들고 추가하기!(self.product = product)
else:
self.product = product
self.add_error('quantity', '값이 없습니다')
self.add_error('product', '값이 없습니다')
from django.shortcuts import render, redirect
from .forms import RegisterForm
from django.views.generic.edit import FormView
# Create your views here.
class OrderCreate(FormView):
# 화면은 따로 구연할 필요 없기 때문에 template_name = 은 생략
form_class = RegisterForm
success_url = '/product/'
# 실패했을 때 redirect하는 함수
# 숫자형이기 때문에 문자열로 변경해주어야 한다
def form_invalid(self, form):
return redirect('/product/'+str(form.product))
# form을 생성할 때 어떤 인자값을 전달해서 만들건지를 결정하는 함수
# formview안에서도request를 전달할 수 있게 해주어야 한다!
def get_form_kwargs(self, **kwargs):
kw = super().get_form_kwargs(**kwargs)
kw.update({
# 기존에 있던 인자 값에다가 request를 포함하겠다!
'request': self.request
})
return kw
from django import forms
from .models import Order
from product.models import Product
from fcuser.models import Fcuser
class RegisterForm(forms.Form):
# 생성자함수
# requst에 전달하기 위해서 생성자 함수를 생성
# product views의 productDetaile에서 form을 생성하는 부분이 있습니다!
# 그리고 order의 views.py에서 request를 처리한다
def __init__(self, request, *args, **kwargs):
# 기존에 있던 생성자를 사용할 수 있도록 super()에서 불러온다!
super().__init__(*args, **kwargs)
self.request = request
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
product = cleaned_data.get('product')
# 사용자 정보!, requst.session에 접근이 필요!
fcuser = self.request.session.get('user')
if quantity and product and fcuser:
order = Order(
quantity=quantity,
product=Product.objects.get(pk=product),
fcuser=Fcuser.objects.get(email=fcuser)
)
order.save()
# 실패했을 경우에
# 템플릿 이름이 지정되지 않아 이대로면 오류가 난다
# 주문하기 페이지를 따로 만들지 않기 때문에 템플릿을 만들필요는 없다!
# Order의 views에 함수를 만들고 추가하기!(self.product = product)
else:
self.product = product
self.add_error('quantity', '값이 없습니다')
self.add_error('product', '값이 없습니다')
from django import forms
from .models import Order
from product.models import Product
from fcuser.models import Fcuser
# transaction 인터페이스
from django.db import transaction
class RegisterForm(forms.Form):
# 생성자함수
# requst에 전달하기 위해서 생성자 함수를 생성
# product views의 productDetaile에서 form을 생성하는 부분이 있습니다!
# 그리고 order의 views.py에서 request를 처리한다
def __init__(self, request, *args, **kwargs):
# 기존에 있던 생성자를 사용할 수 있도록 super()에서 불러온다!
super().__init__(*args, **kwargs)
self.request = request
quantity = forms.IntegerField(
error_messages={
'required': '수량을 입력해주세요.'
}, label='수량'
)
# 실제로 입력받는 값이 아니라 선택한 상품의 아이디를 받아옴
# widget=forms.HiddenInput
product = forms.IntegerField(
error_messages={
'required': '재고를 입력해주세요.'
}, label='재고', widget=forms.HiddenInput
)
# validate
def clean(self):
cleaned_data = super().clean()
quantity = cleaned_data.get('quantity')
product = cleaned_data.get('product')
# 사용자 정보!, requst.session에 접근이 필요!
fcuser = self.request.session.get('user')
if quantity and product and fcuser:
# 이렇게 with으로 감싸서 atomic()으로 묶어주게 되면
# with안에서 일어나는 모든 데이터베이스 관련 동작들은
# 트랜잭션으로 처리
with transaction.atomic():
prod = Product.objects.get(pk=product)
order = Order(
quantity=quantity,
product=Product.objects.get(pk=product),
fcuser=Fcuser.objects.get(email=fcuser)
)
order.save()
# 수량만큼 재고에서 차감
prod.stock -= quantity
prod.save()
# 실패했을 경우에
# 템플릿 이름이 지정되지 않아 이대로면 오류가 난다
# 주문하기 페이지를 따로 만들지 않기 때문에 템플릿을 만들필요는 없다!
# Order의 views에 함수를 만들고 추가하기!(self.product = product)
else:
self.product = product
self.add_error('quantity', '값이 없습니다')
self.add_error('product', '값이 없습니다')
{% extends "base.html" %}
{% load humanize%}
{% block contents %}
<div class="row mt-5">
<div class="col-12">
<div class="card" style="width: 100%;">
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
</div>
<ul class="list-group list-group-flush">
<li class="list-group-item">
<form method="POST" action="/order/create/">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
{% ifnotequal field.name 'product' %}
<label for="{{ field.id_for_label}}">{{field.label}}</label>
{% endifnotequal %}
<input type="{{field.field.widget.input_type}}" class="form-control"
id="{{ field.id_for_label}}" placeholder="{{field.label}}" name="{{field.name}}"
value="{% ifequal field.name 'product' %}{{ product.id }}{% endifequal %}" />
</div>
{% if field.errors %}
<span style="color: red;">{{ field.errors }}</span>
{% endif %}
{% endfor %}
<button type="submit" class="btn btn-primary">주문하기</button>
</form>
</li>
<li class="list-group-item">가격 : {{ product.price|intcomma }} 원</li>
<li class="list-group-item">등록날짜 : {{ product.register_date|date:'Y-m-d H:i' }}</li>
<!-- description은 태그이기 때문에 필터로 |safe를 해주면 html 태그로 만들어준다! -->
<!-- 재고 출력 -->
<li class="list-group-item">재고 : {{ product.stock|intcomma }} 개</li>
<li class="list-group-item">{{ product.description|safe }}</li>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<a href="/product/">목록보기</a>
</div>
</div>
</div>
{% endblock %}