위코드 부트캠프 11기 1차 프로젝트 Hipce팀의 hince클론 입니다.
메이크업 브랜드 힌스를 클론함으로써 데이터 모델링, 회원가입, 로그인, 장바구니와 상품구매 등의 쇼핑몰 핵심 기능을 구현하고 개발 역량을 기르고자 한다.
팀의 분위기
다들 첫 프로젝트라 어렵고, 원하는데로 코드 구현이 안되어 답답했을텐데 누구하나 짜증내는 팀원 없이 서로가 할 수 있다며, 응원하고 격려하며 밝은 분위기가 이어질 수 있게 노력해준 팀원들 덕분에 지난 2주가 즐거웠습니다.
팀의 좋은 분위기가 결국 좋은 프로젝트 결과물로 이어질 수 있게 된거 같습니다.
코드 가독성 고려
이번 프로젝트를 하면서 코드가 난잡하지 않게, 누구나 코드를 보고 이해 할 수있게 최대한 가독성을 고려해 가면서 코드를 작성했습니다.
보기 편하게 커밋 메세지 작성
커밋을 할때, 변경점이 무엇인지 알기 쉽도록 커밋 메세지를 작성했습니다.
로그인시 발행한 Access token을 리뷰작성할때 데코레이터를 통해서 유저의 로그인 유무를 확인하여 HTTP는 'Stateless'다!를 단순한 지식이 아닌 실제 코드로 기능 구현을 통해서 경험하게 되어 가장 인상 깊었습니다.
import json, jwt
from django.views import View
from django.http import JsonResponse
from .models import User
from hince.settings import SECRET_KEY, ALGORITHM
def login_confirm(original_function):
def wrapper(self, request):
try:
access_token = request.headers.get("Authorization", None)
if access_token:
token_paylod = jwt.decode(access_token, SECRET_KEY['secret'], ALGORITHM['algorithm'])
request.account = User.objects.get(id = token_paylod['USER_ID'])
return original_function(self, request)
return JsonResponse({'MESSAGE':'LOGIN_REQUIRED'}, status = 401)
except jwt.DecodeError:
return JsonResponse({'MESSAGE':'INVALID_USER1'}, status = 401)
except User.DoesNotExist:
return JsonResponse({'MESSAGE':'INVALID_USER2'}, status = 401)
return wrapper
이번 1차 프로젝트에서 제가 단독으로 맡은 기능은 회원가입과 로그인, 리뷰 기능 구현과 리뷰에 달리는 댓글을 구현하는 것인데, 이중에서도
리뷰와 리뷰에 댓글 작성 기능을 구현하면서 CRUD 전체를 한번 구현해본것이 이번 1차 프로젝트를 통해서 얻은 값진 경험이였습니다.
import bcrypt, json, jwt, re
from django.views import View
from django.http import JsonResponse
from user.utils import login_confirm
from .models import Review, ReviewImage, ReviewReply
from user.models import User
from product.models import Product
class ReviewView(View):
def get(self, request, id):
try:
# data = json.loads(request.body)
reviews = Review.objects.filter(product_id = id).prefetch_related('reviewimage_set')
# reviews = Review.objects.filter(product_id = data['product_id']).prefetch_related('reviewimage_set')
results = []
for review in reviews:
image_list = []
for images in review.reviewimage_set.all():
image_list.append((images.id, images.image))
results.append({
'user_id' : review.user_id,
'review_id' : review.id,
'content' : review.content,
'product_id' : review.product_id,
'review_id_images': image_list,
})
return JsonResponse({'Review': results}, status = 200)
except json.decoder.JSONDecodeError:
return JsonResponse({"MESSAGE": "JSONDecodeError"}, status = 401)
@login_confirm
def post(self, request):
try:
data = json.loads(request.body)
review = Review.objects.create(
user = request.account,
product = Product.objects.get(id = data['product_id']),
content = data['content'],
scroe = data['score']
)
review_iamge = ReviewImage.objects.create(
review = review,
image = data['image']
)
return JsonResponse({"MESSAGE": "SUCCESS"}, status = 200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status = 400)
@login_confirm
def put(self, request):
try:
data = json.loads(request.body)
user_id = request.account.id
review_id = data['review_id']
modification_review = Review.objects.get(
user = user_id,
id = review_id
)
modification_review.content = data['content']
modification_review.save()
if data['image']:
modification_review_image = ReviewImage.objects.get(id = data['image_id'])
modification_review_image.image = data['image']
modification_review_image.save()
return JsonResponse({"MESSAGE": "Changed_review_image"}, status = 200)
pass
return JsonResponse({"MESSAGE": "Changed_review"}, status = 200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status = 400)
except json.decoder.JSONDecodeError:
return JsonResponse({"MESSAGE": "JSONDecodeError"}, status = 401)
@login_confirm
def delete(self, request):
try:
data = json.loads(request.body)
Review.objects.filter(id = int(data['review_id'])).delete()
return JsonResponse({"MESSAGE": "Review was deleted"}, status = 200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status = 400)
class ReviewReplyView(View):
def get(self, request, id):
try:
results = []
review_replys = ReviewReply.objects.filter(review_id = id)
for review_reply in review_replys:
results.append({
'user_id' : review_reply.user_id,
'review_reply_id' : review_reply.id,
'comment' : review_reply.comment
})
return JsonResponse({'Review_Reply': results}, status = 200)
except json.decoder.JSONDecodeError:
return JsonResponse({"MESSAGE": "JSONDecodeError"}, status = 401)
@login_confirm
def post(self, request):
try:
data = json.loads(request.body)
ReviewReply.objects.create(
user = request.account,
review = Review.objects.get(id = data['review_id']),
comment = data['comment']
)
return JsonResponse({"MESSAGE": "SUCCESS"}, status = 200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status = 400)
@login_confirm
def put(self, request):
try:
data = json.loads(request.body)
user_id = request.account.id
comment_id = data['comment_id']
modification_review_reply = ReviewReply.objects.get(
user = user_id,
id = comment_id
)
modification_review_reply.comment = data['comment']
modification_review_reply.save()
return JsonResponse({"MESSAGE": "Change_review_reply"}, status = 200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status = 400)
except json.decoder.JSONDecodeError:
return JsonResponse({"MESSAGE": "JSONDecodeError"}, status = 401)
@login_confirm
def delete(self, request):
try:
data = json.loads(request.body)
ReviewReply.objects.get(id = data['comment_id']).delete()
return JsonResponse({"MESSAGE": "ReviewReply was deleted"}, status = 200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status = 400)