기존에 인스타그램 클론코딩했던 소스를 수정하여 쇼핑몰로 변경합니다.
제품 상세 페이지 만들기
페이지 기본 구성 만들기
조금씩 수정하면서 수정된 내용을 바로 확인해볼 수 있도록 html, views.py, urls.py 모두 생성합니다.
1. templates > content 안에 ‘productdetail.html’ 파일을 생성하고, 부트스트랩 스타터를 복사하여 붙여넣어 기본적인 틀을 만들어 줍니다.
2. content > views.py 안에 위 html 페이지를 띄우는 로직을 만듭니다.
class ProductDetail(APIView):
def get(self, request, pk):
return render(request, 'content/productdetail.html')
3. urls.py 안에 path('product/', ProductDetail.as_view(), name='product')를 입력합니다.
4. 기본 페이지가 보이는지 웹으로 접속하여 확인 합니다.
디테일 잡기
1. 네비게이션 바가 보여지게 main.html에서 해당 코드를 복사해 붙여 넣고, Head 안에 {% load static %} 도 입력합니다.
2. 상품 이미지와 정보화면에 대한 코딩을 입력합니다.
<div style="display: flex; flex-direction: row; padding-top: 50px">
<div style="width: 50%; height: 50%; margin:50px">
<img style="width: 100%; height: 100%" src="{% get_media_prefix %}{{ product.image }}">
</div>
<div style="width: 50%; height: 50%; margin: 50px">
<hr>
<div style="font-size: 36px">
{{ product.description }}
</div>
<hr>
<div>
<span style="margin-right: 100px;font-size: 24px"> 판매가 </span>
<span style="font-size: 36px; color: red"> {{ product.price }} 원</span>
</div>
<hr>
<div>
<span style="margin-right: 80px;font-size: 24px"> 배송방법 </span>
<span style="font-size: 20px"> 택배 </span>
</div>
<hr>
<div>
<span style="margin-right: 100px;font-size: 24px"> 배송비 </span>
<span style="font-size: 20px"> 무료</span>
</div>
<hr>
<div>
<button type="button" class="btn btn-dark"> 바로 구매하기</button>
<button type="button" class="btn btn-secondary"> 장바구니 담기</button>
<button type="button" class="btn btn-secondary"> 관심상품등록</button>
</div>
<div style="margin-top: 100px;">
<button type="button" class="btn btn-warning" style="width: 100%">카카오톡 공유하기</button>
</div>
<div style="margin-top: 5px">
<button type="button" class="btn btn-success" style="width: 100%">네이버 공유하기</button>
</div>
</div>
</div>
3. 실제 제품 정보를 불러올 수 있도록 views.py의 내용을 수정합니다.
Product 테이블에 있는 정보 중 id가 1인 상품정보를 html에 전달합니다.
class ProductDetail(APIView):
def get(self, request):
product = Product.objects.get(id=1)
return render(request, 'content/productdetail.html', context=dict(product=product))
하드 코딩으로 넣은 제품의 정보가 아닌 메인에서 상품을 선택했을 때 해당 상품의 상세 페이지를 보여줄 수 있도록 상품 식별값을 pk로 받아오게 설정합니다.
class ProductDetail(APIView):
def get(self, request, pk):
product = Product.objects.get(id=pk)
return render(request, 'content/productdetail.html', context=dict(product=product))
검색 만들기
네비게이션바의 검색창에서 특정 상품만을 검색할 수 있도록 수정합니다.
상품 리스트가 나오는 과정을 조금만 수정하면 되는데, `Product.objects.all()`은 모든 상품을 전달하는 반면 `Product.objects.filter({키워드})`를 쓰면 키워드를 기준으로 테이블 내에서 정보를 걸러서 보여준다는 점을 활용합니다.
1. main.html에서 <from> 수정하기
네비게이션바 위치에서 Search 부분을 찾습니다.
ajax처럼 <form>에서도 action으로 동작을 추가할 수 있는데, 검색할 때 ‘search’ 경로의 로직을 POST로 실행하도록 아래와 같이 추가하면서 입력한 검색어에 대해서는 keyword라는 이름을 지정합니다.
<form action="{% url 'search' %}" method="post" class="d-flex">
<input class="form-control me-2" type="search" name="keyword" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
2. 메인 views.py에 있는 class Main을 복사하여 Search로 수정합니다.
class Search(APIView):
def post(self, request):
if request.session.get('login_check'):
email = request.session.get('email')
find_user = User.objects.filter(email=email).first()
keyword = request.data.get('keyword')
return render(request, 'learningspoons/main.html',
context=dict(
data_list=Product.objects.filter(description__contains=keyword).order_by('-id'),
user_info=find_user
))
else:
return render(request, 'user/login.html')
3. urls.py에서 path('search/', Search.as_view(), name='search')를 입력합니다.
홈 로고 수정하기
로고를 누르면 메인 홈페이지로 이동할 수 있도록 href의 내용을 수정합니다.
href에 적혀있는 “#” 대신 “/” 혹은 “{% url ‘main’ %}”을 입력하여 메인 페이지 경로로 지정해줍니다.
장바구니 만들기
장바구니 정보 테이블 만들기
models.py에서 장바구니 정보를 담을 cart 테이블을 아래와 같이 생성합니다.
상품정보나 가격을 장바구니 테이블에 중복저장하지 않고 product_id 값을 이용해 product 테이블에서 가져올 수 있도록 설정합니다.
class Cart(models.Model):
email = models.TextField()
product_id = models.IntegerField()
count = models.IntegerField()
class Meta:
unique_together = ('email', 'product_id')
장바구니에 담기 버튼 동작 만들기
productdetail.html에서 [장바구니 담기] 버튼을 눌렀을 때, 해당 상품의 product_id를 뒤에 만들 AddCart 로직으로 전송할 수 있도록 ajax를 작성합니다.
$('#add_cart').click(function () {
$.ajax({
url: {% url 'addcart' %},
method: 'POST',
data: {
product_id: {{ product.id }}
},
success: function (data) {
alert('장바구니에 추가되었습니다.')
},
error: function (request, status, error) {
alert('장바구니에 추가 실패')
},
})
})
장바구니에 데이터 저장하는 로직 만들기
views.py에서 상품 정보를 Cart 테이블에 저장하는 로직을 작성합니다.
class AddCart(APIView):
def post(self, request):
email = request.session.get('email') # 세션에서 email값 가져오기
product_id = request.data.get('product_id') # 인풋에서 product_id값 가져오기
if Cart.objects.filter(email=email, product_id=product_id).exists():
# 만약 장바구니에 같은 상품이 있으면 더하기
cart_in_db = Cart.objects.filter(email=email, product_id=product_id).first()
cart_in_db.count = cart_in_db.count + 1
cart_in_db.save()
else:
# 장바구니에 같은 상품이 없으면 생성
Cart.objects.create(email=email, product_id=product_id, count=1)
return Response(status=200)
urls.py에서 path('addcart/', AddCart.as_view(), name='addcart')를 추가합니다.
장바구니 화면 만들기
cart.html을 새로 만들어서 장바구니 테이블에 담긴 정보를 표시할 화면을 구성합니다.
<div style="display: flex; flex-direction: row;">
<div style="width: 200px;text-align: center">상품 이미지</div>
<div style="width: 500px;text-align: center">상품정보</div>
<div style="width: 200px;text-align: center">가격</div>
<div style="width: 50px;text-align: center">수량</div>
</div>
views.py에 사용자의 장바구니 아이템을 내려주는 코드를 작성합니다.
class CartView(APIView):
def get(self, request):
email = request.session.get('email') # 세션에서 email값 가져오기
cart_item_list = Cart.objects.filter(email=email) # 로그인한 사용자의 장바구니 아이템 전부 가져오기
data_list = [] # 빈 리스트 생성
for cart_item in cart_item_list:
# 사용자의 카트 아이템들을 하나씩 보면서 상품정보를 불러옴
product = Product.objects.get(id=cart_item.product_id)
# data_list에 하나씩 추가
data_list.append(dict(
product=product,
count=cart_item.count
))
return render(request, 'content/cart.html', context=dict(data_list=data_list))
views.py에서 넘어온 데이터를 for문으로 하나씩 출력하는 코드를 cart.html에 추가로 작성합니다.
{% for data in data_list %}
<div style="display: flex; flex-direction: row;">
<div style="width: 200px"><img width="150px" src="{% get_media_prefix %}{{ data.product.image }}"></div>
<div style="width: 500px">
<div> {{ data.product.seller }}</div>
<div style="font-size: 24px"> {{ data.product.description }}</div>
</div>
<div style="width: 200px;font-size: 24px; color: red">{{ data.product.price }} 원 </div>
<div style="width: 50px;text-align: center">{{ data.count }}</div>
</div>
<hr>
{% endfor %}
이것저것 장바구니에 넣어 출력되는 화면을 확인합니다.
'Django(웹서비스 만들기)' 카테고리의 다른 글
[10주차] 프로젝트-2 (0) | 2022.01.30 |
---|---|
[9주차] 프로젝트-1 (0) | 2022.01.15 |
[7주차] 여러 서비스 연계하기 (0) | 2022.01.08 |
[6주차] AWS에 웹 서비스 배포하기 (0) | 2021.12.29 |
[5주차] Git 사용하기 (0) | 2021.12.24 |