2차 프로젝트

박경철·2021년 6월 26일
0

Project

목록 보기
2/2

1. 프로젝트 소개

국내, 해외 어디를 가더라도 항공, 숙박, 티켓, 투어, 액티비티 여행 예약 플랫폼 마이리얼트립! '마이 리얼 트립'(https://www.myrealtrip.com/) 웹사이트 클론.

2. 구현범위 설정

2.1 필수 구현

  • 회원가입 (소셜)
  • 로그인( 소셜)
  • 상세페이지 - 옵션 선택
  • 카테고리리스트
  • 메인리스트 - 랜드마크

2.2 추가 구현

  • 상세페이지 - 리뷰
  • 상세페이지 - 메인페이지 로직 적용
  • 위시리스트
  • 검색기능

3. 모델링

4. 기능구현

Product Detail 페이지 구현
(DB Hit 줄이기 위해 Prefetch 사용)

class ProductView(View):
    def get(self, request, product_id):
        product = Product.objects.filter(id=product_id).prefetch_related(
            'review_set', 'review_set__user','review_set__reviewimage_set',
            'option_set', 'option_set__date_set').first()

        if not product:
            return JsonResponse({'message':'NOT EXIST'}, status=404)

        total_score = product.review_set.aggregate(Avg('score'))['score__avg']

        result = {
            'name'         : product.name,
            'price'        : product.price,
            'discount'     : product.discount,
            'main_image'   : product.main_image,
            'detail_image' : product.detail_image,
            'total_score'  : total_score if total_score != None else 0,
            'total_review' : product.review_set.count() if product.review_set.count() > 0 else 0,
            'reviews'      : [{
                'user'         : review.user.name,
                'contents'     : review.contents,
                'score'        : review.score,
                'manager_text' : review.manager_text,
                'create_at'    : review.create_at,
                'update_at'    : review.update_at,
                'images'       : [data.image for data in review.reviewimage_set.all()]
            }for review in product.review_set.all()],
            'options'      : [{
                'name'  : option.name,
                'price' : option.price,
                'dates' : [data.date for data in option.date_set.all()]
            } for option in product.option_set.all()]
        }

        return JsonResponse({'product':result}, status=200)

Option 선택 기능

class OptionView(View):
    def post(self, request):
        try:
            data = json.loads(request.body)
            date = Date.objects.get(id=data['option_id'])
        
            result = (True if date.count > data['count'] else False)

            return JsonResponse({'status':result}, status=200)

        except Date.DoesNotExist:
            return JsonResponse({'message':'NOT EXIST'}, status=404)

Review View 기능

class ReviewView(View):
    def get(self, request):
        product_id = request.GET.get('product_id')
        offset     = int(request.GET.get('offset',0))
        limit      = int(request.GET.get('limit',3))

        reviews = Review.objects.filter(product_id=product_id).prefetch_related('user','reviewimage_set')[offset:limit]

        result = [{
                'user'         : review.user.name,
                'contents'     : review.contents,
                'score'        : review.score,
                'manager_text' : review.manager_text,
                'create_at'    : review.create_at,
                'update_at'    : review.update_at,
                'images'       : [data.image for data in review.reviewimage_set.all()]
                } for review in reviews]

        return JsonResponse({'reviews':result}, status=200)

Test.py 작성

class ProductTestCase(TestCase):
    @classmethod
    def setUpTestData(cls):
        MainCategory.objects.create(id=1,name='test')
        SubCategory.objects.create(id=1,name='test', maincategory_id=1)
        Region.objects.create(id=1,name='test')
        User.objects.create(id=1,name='test', password='123')
        Product.objects.create(
            id=1,
            name='test',
            price=Decimal(123.00),
            discount=0.1,
            main_image='test',
            detail_image='test',
            subcategory_id=1,
            region_id=1
        )
        Option.objects.create(
            id=1,
            name='test',
            price=Decimal(1),
            product_id=1
        )
        Date.objects.create(
            id=1,
            date=datetime.strptime('2021-06-26', '%Y-%m-%d'),
            count=1,
            option_id=1
        )
        Review.objects.create(
            id=1,
            contents='test',
            score=1,
            manager_text='test',
            product_id=1,
            user_id=1
        )
        ReviewImage.objects.create(id=1, image='test', review_id=1)
    
    def tearDown(self):
        User.objects.all().delete()
        MainCategory.objects.all().delete()
        SubCategory.objects.all().delete()
        Region.objects.all().delete()
        Product.objects.all().delete()
        Date.objects.all().delete()
        Option.objects.all().delete()
        Review.objects.all().delete()
        ReviewImage.objects.all().delete()

    def test_get_product(self):
        client = Client()

        data = {
            'name'         : 'test',
            'price'        : '123.00',
            'discount'     : 0.1,
            'main_image'   : 'test',
            'detail_image' : 'test',
            'total_score'  : 1.0,
            'total_review' : 1,
            'reviews'      : [{
                'user'        : 'test',
                'contents'    : 'test',
                'score'       : 1,
                'manager_text': 'test',
                'create_at'   : '',
                'update_at'   : '',
                'images'       : ['test']
            }],
            'options'   : [{
                'name'  : 'test',
                'price' : '1.00',
                'dates' : ['2021-06-26']
            }]
        }

        response = client.get('/products/1', content_type = 'application/json')
        response_data = response.json()
        
        data['reviews'][0]['create_at'] = response_data['product']['reviews'][0]['create_at']
        data['reviews'][0]['update_at'] = response_data['product']['reviews'][0]['update_at']
        
        self.assertEqual(response.json(),{'product':data})
        self.assertEqual(response.status_code, 200)
    
    def test_get_product_error(self):
        client = Client()

        response = client.get('/products/2', content_type = 'application/json')

        self.assertEqual(response.json(),{'message':'NOT EXIST'})
        self.assertEqual(response.status_code, 404)

5. 협업도구

  • Trello
  • Git
  • GitHub
  • Slack

6. 회고록

  • 데이터베이스 모델링의 중요성
  • 협업 및 소통
  • 리펙토링

7. 참고자료

profile
안녕하세요!

0개의 댓글