위코드 1차 프로젝트 리뷰 - Backend 기준

Taeha Kim·2020년 9월 1일
0

PROJECT

목록 보기
1/3
post-thumbnail

위코드 1차 프로젝트 리뷰

위코드 부트캠프 11기 1차 프로젝트 Hipce팀의 hince클론 입니다.

개발 인원 및 기간

개발 인원

개발 기간

  • 2020/08/17 ~ 2020/08/30

프로젝트 목적

메이크업 브랜드 힌스를 클론함으로써 데이터 모델링, 회원가입, 로그인, 장바구니와 상품구매 등의 쇼핑몰 핵심 기능을 구현하고 개발 역량을 기르고자 한다.

Modeling

적용 기술 및 구현된 기능

Frontend, Backend 공통

  • JSON
  • Git
  • Linux
  • HTTP
  • Scrum 방식의 프로젝트 진행

Backend 적용 기술

  • Python, Django web framework
  • Bcrypt
  • JWT
  • MySQL
  • AWS EC2, RDS

내가 구현 기능 및 한 일들

  • 회원가입시 정규식을 이용한 유효성 검사
  • Bcrypt를 활용한 비밀번호 암호화
  • JWT를 활용한 Access token 발행
  • 리뷰 작성, 리뷰 보기, 리뷰 수정, 리뷰 삭제
  • 리뷰에 댓글 작성, 댓글 확인, 댓글 수정, 댓글 삭제

잘한점

  • 팀의 분위기
    다들 첫 프로젝트라 어렵고, 원하는데로 코드 구현이 안되어 답답했을텐데 누구하나 짜증내는 팀원 없이 서로가 할 수 있다며, 응원하고 격려하며 밝은 분위기가 이어질 수 있게 노력해준 팀원들 덕분에 지난 2주가 즐거웠습니다.
    팀의 좋은 분위기가 결국 좋은 프로젝트 결과물로 이어질 수 있게 된거 같습니다.

  • 코드 가독성 고려
    이번 프로젝트를 하면서 코드가 난잡하지 않게, 누구나 코드를 보고 이해 할 수있게 최대한 가독성을 고려해 가면서 코드를 작성했습니다.

  • 보기 편하게 커밋 메세지 작성
    커밋을 할때, 변경점이 무엇인지 알기 쉽도록 커밋 메세지를 작성했습니다.

아쉬운점

  • 프론트엔드와의 소통
    프로젝트를 시작하면서 백엔드 멘토님은 백엔드는 프론트엔드와의 소통이 중요하다고 하시고, 프론트엔드 멘토님들은 프론트엔드는 백엔드와의 소통이 중요하다고 계속 언급 하셨는데, '무엇때문에 저렇게 강조를 하실까?' 하며 이해못하고 프로젝트를 진행했었습니다. 프로젝트 초반에는 특별한 문제가 없어 보였는데, 프로젝트 중반부터 끝날때까지 서로 주고 받는 데이터의 형식, 키값, 엔드포인트까지 합의된거 없이 각자 만들었다가 다시 전부 수정하는 경험을 했습니다.
    단순히 팀의 밝은 분위기를 위해서 서로 소통하라는게 아님을 몸소 체험하고 나서야 2차 프로젝트때는 정말 하나하나 프론트엔드와 맞춰야겠다고 생각했습니다.

기억에 남는 코드

1) Access token으로 로그인 확인(데코레이터)

로그인시 발행한 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

2) 리뷰작성과 리뷰에 댓글 작성(CRUD)

이번 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)
profile
함께 성장하는 개발자가 되고 싶습니다.

0개의 댓글