1차 Project - 3

Jina·2020년 5월 4일
0

Project

목록 보기
4/7

Step 4. View 만들기

기록하고 싶은 view

Image url보내기

 def image_format(image_name, params):    # 3-1
     formats = {
          'exterior'  : { 'mvl' : params['mvl'], 'caliper_code' : params['caliper_code'], 'wheel_code' : params['wheel_code'], 'exterior_code' : params['exterior_code']},
          'interior1' : { 'mvl' : params['mvl'], 'carpet_code' : params['carpet_code'], 'dashboard_code2' : params['dashboard_code2'], 'dashboard_code1' : params['dashboard_code1'], 'steering_code' : params['steering_code'], 'seat_code2' : params['seat_code2'], 'seat_code1' : params['seat_code1']},
          'interior2' : { 'mvl' : params['mvl'], 'seat_code2' : params['seat_code2'], 'seat_code1' : params['seat_code1'], 'dashboard_code1' : params['dashboard_code1'], 'dashboard_code2' : params['dashboard_code2'], 'steering_code' : params['steering_code']},
          'interior3' : { 'mvl' : params['mvl'], 'carpet_code' : params['carpet_code'], 'seat_code2' : params['seat_code2'], 'seat_code1' : params['seat_code1'], 'dashboard_code1' : params['dashboard_code1'], 'dashboard_code2' : params['dashboard_code2']},
          'interior4' : { 'mvl' : params['mvl'], 'carpet_code' : params['carpet_code'], 'seat_code2' : params['seat_code2'], 'seat_code1' : params['seat_code1'], 'dashboard_code1' : params['dashboard_code1'], 'dashboard_code2' : params['dashboard_code2'], 'steering_code' : params['steering_code'], 'exterior_code' : params['exterior_code']}
         }

     return formats.get(image_name, "Invalid_name")    # 3-2
     
 class MainView(View):
     def get(self, request):
         try:
	     # 1
             mvl       = ModelVersionLine.objects.get(id = request.GET.get('mvl')).code
             exterior  = ExteriorGroup.objects.select_related('exterior', 'wheel', 'caliper').get(exterior = request.GET.get('exterior'), wheel = request.GET.get('wheel'), caliper = request.GET.get('caliper'))
             interior  = InteriorGroup.objects.select_related('seat', 'dashboard', 'carpet', 'steering').get(seat = request.GET.get('seat'), dashboard = request.GET.get('dashboard'), carpet = request.GET.get('carpet'), steering = request.GET.get('steering'))

	     # 2.
             one_dict = {}
             one_dict['mvl'] = mvl; one_dict['caliper_code'] = exterior.caliper.code; one_dict['wheel_code'] = exterior.wheel.code; one_dict['exterior_code'] = exterior.exterior.code;
             one_dict['carpet_code'] = interior.carpet.code; one_dict['dashboard_code1'] = interior.dashboard.code1; one_dict['dashboard_code2'] = interior.dashboard.code2;
             one_dict['steering_code'] = interior.steering.code; one_dict['seat_code1'] = interior.seat.code1; one_dict['seat_code2'] = interior.seat.code2

	     # 3.
             image_url = lambda img_name: ImageUrl.objects.get(name = img_name).image_url

             exterior_url = [
              {   'Exterior1'  : image_url("main_exterior1").format(**image_format('exterior', one_dict)),
                  'Exterior2'  : image_url("main_exterior2").format(**image_format('exterior', one_dict)),
                  'Exterior3'  : image_url("main_exterior3").format(**image_format('exterior',one_dict)),
                  'Exterior4'  : image_url("main_exterior4").format(**image_format('exterior',one_dict)),
                  'Interior1'  : image_url("main_interior1").format(**image_format('interior1',one_dict)),
                  'Interior2'  : image_url("main_interior2").format(**image_format('interior2',one_dict)),
                  'Interior3'  : image_url("main_interior3").format(**image_format('interior3',one_dict)),
                  'Interior4'  : image_url("main_interior4").format(**image_format('interior4',one_dict)),
                  'preview'    : image_url("main_preview_url").format(**image_format('exterior',one_dict))
               }
           ]
             return JsonResponse({'rendering_url': exterior_url}, status = 200)

         except KeyErrorr:
             return HttpResponse(status = 400)
         except ObjectDoesNotExist:
             return HttpResponse(status = 400)     

1) 쿼리스트링으로 들어오는 mvl, exterior, interior에 대한 정보를 저장하였다.

mvl은 들어오는 mvl_id의 code를 저장하였다.
exterior는 exterior,wheel,caliper의 id를 묶어서 저장하였다.
interior는 seat,dashboard,carpet,steering의 id를 묶어서 저장하였다.

2) one_dict

one_dict = {} 를 이용하여 빈 딕셔너리를 만들고
아래의 문장들을 이용하여 각각의 내용을 딕셔너리에 저장하였다.

3)
lambda를 이용하였다.

lambda
람다는 아래의 사진과 같이 사용한다. 아래 사진의 내용은 여기서 확인할 수 있다.

Exterior1 을 예시로 설명하면 아래와 같다.

image_url = lambda img_name: ImageUrl.objects.get(name = img_name).image_url

'Exterior1'  : image_url("main_exterior1").format(**image_format('exterior', one_dict))

'Exterior1'은 lambda에 의해

ImageUrl.objects.get(name = "main_exterior1").image_url.format ~~ 과 같아진다.

즉 image_url("main_exterior1") = ImageUrl.objects.get(name = "main_exterior1").image_url 인 것이다.

여기서 ImageUrl은 각 image의 image_url의 틀의 내용을 담고있다. 이 틀에 각 option의 코드를 입력하면 한 사진의 url이 완성되는 형식인 것이다.

여기서 main_exterior1의 image_url의 틀은 아래와 같다.

'https://ph.cloud.maserati.com/{mvl}/1280/c720/gfx6?config=background;shadow;CRPT/CRPT/94084217;INT/INT/94084310;BOE/Q136/INT/94084310;DUMMYOPTS/DOARM/94084281;DUMMYOPTS/DOPUH/94084282;TRIM/Q4MN;RUF/ROO1/94084295;DSH/DSHG/94084275;STEERINGWHEEL/STL1/94084213;BOE/Q5ZK;BOE/Q4B2;BOE/Q407;BOE/QAWS;FUS/Q410;CAL/{caliper_code};RIMS/{wheel_code};EXT/EXT/{exterior_code};MEC/Q5EM;glasses_front;MEC/Q400\n'

위의 url중 {mvl},{caliper_code},{wheel_code},{exterior_code} 에 선택 사항의 색상 code를 입력하면 각 옵션이 적용된 이미지 url이 나타난다.

{}안에 code를 채워넣기 위해 format(**image_format('exterior', one_dict)) 를 이용한다.
이 코드를 이용하여 위의 image_url("main_exterior1")을 def image_format에 적용하였다.

3-1) format(**image_format('exterior', one_dict))

여기서 **은 값을 def image_format의 인자를 딕셔너리 형태로 받겠다는 뜻이다.

formats 딕셔너리의 'exterior' 를 이용하고 그 곳의 params에 one_dict를 넣어서 url의 비어있는 코드 부분에 값을 받는 형식이다.

3-2) return formats.get(image_name, "Invalid_name")

여기서 사용한 get은 딕셔너리의 메소드 get!
formats 딕셔너리에 image_name이라는 key가 있으면 해당 key의 value를 리턴하고 key가 존재하지 않는다면 "Invalid_name"을 return한다.

여기서는 image_name이 'exterior'이다. 따라서 formats 딕셔너리의 'exterior' value인 코드가 리턴된다.

내 차량 정보 저장하기

from django.db               import transaction

class CustomCarView(View):
     @transaction.atomic    # 1
     def post(self,request):
         data                = json.loads(request.body)
         contact_channel     = data['contact_channel']
         model_version_line  = data['mvl']
         exterior            = data['exterior']
         wheel               = data['wheel']
         caliper             = data['caliper']
         seat                = data['seat']
         dashboard           = data['dashboard']
         carpet              = data['carpet']
         steering            = data['steering']
         package_list        = data.get('package',None)
         accessory_list      = data.get('accessory',None)

         try:
             # 2.
             CustomCarOption.objects.create(
                     model_version_line   = ModelVersionLine.objects.get(id=model_version_line),
                     exterior_group       = ExteriorGroup.objects.get(exterior_id=exterior,wheel_id=wheel,caliper_id=caliper),
                     interior_group       = InteriorGroup.objects.get(seat_id=seat,dashboard_id=dashboard,carpet_id=carpet,steering_id=steering)
                  )
             # 3.
             if package_list:
                 for packages in package_list:
                     PackageCustomCar.objects.create(
                         package           = Package.objects.get(id=packages),
                         custom_car_option = CustomCarOption.objects.last()
                     )
             # 4.
             if accessory_list:
                 for accessories in accessory_list:
                     CustomCarAccessory.objects.create(
                         quantity          = accessories.get('quantity'),
                         accessory         = Accessory.objects.get(id=accessories.get('id')),
                         custom_car_option = CustomCarOption.objects.last()
                  )
			
             for contact in contact_channel :
                 ContactChannel.objects.create(
                     mail = contact['mail'],
                     call = contact['call'],
                     sns = contact['sns'],
                     sms = contact['sms'],
                     fax = contact['fax'],
                     email = contact['email']
             )
	     # 5.
             code_id = str(CustomCar.objects.count())[-1]
             CustomCar.objects.create(
                 email = data['name'],
                 name = data['name'],
                 code = (str(uuid.uuid4())[0:5]+str(uuid.uuid4)[1:3]+code_id).upper(),
                 contact_channel = ContactChannel.objects.last(),
                 privacy_check = data['privacy_check'],
                 
                 
             )
         except KeyError:
             return HttpResponse(statu=400)

         return JsonResponse({"code":CustomCar.objects.last().code},status=200)

1) transaction.atomic

tansaction 기능을 이용하였다.

  • 트랜잭션(Transaction)이란?
    • 질의를 하나의 묶음 처리해서 중간에 실행이 중단되면 처음부터 다시 실행(rollback)하고 오류없이 마치면 커밋(commit)하는 것
    • 한번의 질의가 실행되면 모두 실행되거나 모두 실행되지않거나
    • 트랜잭션의 특성 ACID
  • ACID(Atomicity, Consistency, Isolation, Durability)
    원자성, 일관성, 고립성, 지속성

여기 참고하기

2) CustomCarOption.objects.create

먼저 선택한 차량 옵션을 CustomCarOption의 테이블에 저장하도록 했다.

3) package

package는 CustomCarOption과 many to many 필드로 연결되어 있다.
따라서 저장시 위의 예시와 같이 나눠서 저장해주어야한다.

만약 선택한 package가 있다면 CustomCarOption에 함께 저장하도록 했다.

CustomCarOption.objects.last()를 이용하여 마지막에 저장된(2번에서 저장된) CustomCarOption의 id와 연결된다.

4) accessory

accessory는 CustomCarOption과 many to many 필드로 연결되어 있다.
따라서 저장시 위의 예시와 같이 나눠서 저장해주어야한다.

만약 선택한 accessory가 있다면 CustomCarOption에 함께 저장하도록 했다.

CustomCarOption.objects.last()를 이용하여 마지막에 저장된(2번에서 저장된) CustomCarOption의 id와 연결된다.

5) code

차량을 저장하면 code를 생성해서 frontend에게 return해주어야 한다.

code는 아래와 같이 생성했다.

code_id = str(CustomCar.objects.count())[-1]
code = (str(uuid.uuid4())[0:5]+str(uuid.uuid4)[1:3]+code_id).upper()

uuid를 이용하여 code를 생성했다.
uuid4는 랜덤한 id를 만드는 방식이므로 이를 사용하였고 uuid4()를 한번만 사용했을 시 중복되는 경우가 생길 까봐 uuid4()를 두번 사용하고 slicing으로 부분을 잘라서 합쳐주었다.

위의 과정을 거쳤는데도 중복이 생길까봐 code_id라는 것을 만들어서 그 부분도 붙여주었다.
code_id는 저장된 CustomCar의 갯수에 마지막 글자만 자른 숫자이다.
만약 count 갯수가 많아지게 되었을 경우 코드가 너무 길어지기 때문에 count 수 자체를 가지고 오지 않고 맨 마지막 숫자만 가져오도록 했다.

CustomCarOption.objects.last() 를 이용하여 마지막으로 저장된(2번에서 저장된) CustomCarOption의 id와 code를 연결시켰다.

이렇게 연결을 해두면 code를 이용하여 CustomCarOption을 불러올 수 있다.

Step 5. Url 작성

각 class에 맞는 url을 만들어준다.

이 url을 postman을 통해서 frontend와 공유하였다.
url의 목록은 여기를 통해서 볼 수 있다.


위의 과정을 거쳐 API를 완성하였다.
이후로 AWS를 이용하여 프로젝트를 배포하였고, frontend와 결합하며 오류가 생긴 부분을 수정하였다.

2개의 댓글

comment-user-thumbnail
2020년 5월 5일

두콩쓰..

1개의 답글