Django | 부분 업데이트(partial update) in views.py - get 메소드 활용!

Sua·2021년 1월 31일
1

Django

목록 보기
3/23
post-thumbnail
post-custom-banner

장고에서 데이터를 수정하기 위해서는 views.py에 post 메소드 안에 작성된 모든 필드명을 받아야 한다.
(수정은 patchput 메소드도 가능)

예를 들어 하나의 메소드 안에서 korean_name, english_name, description, is_new, category를 수정할 수 있도록 작성했다고 한다면,

프론트 쪽에선 description만 수정하고 싶더라도 5개 모두에 대한 정보를 넘겨줘야 수정이 가능하다. 아니면 KeyError가 나고 수정되지 않는다.

그렇다고 description만 수정하는 메소드를 따로 빼기에는 너무 비효율적이다.

하지만 바로 딕셔너리의 get 메소드를 이용한다면, KeyError없이 일부 필드만 수정할 수 있다!

Update Logic in views.py

우선 views.py에 POST 메소드로 특정 id의 product 정보를 수정하는 로직을 작성하였다.

class ProductDetailView(View): 
    def post(self, request, product_id):
        data = json.loads(request.body)
        category = Category.objects.get(name=data['category'])
        product = Product.objects.get(id=product_id)
        product.korean_name = data['korean_name']
        product.english_name = data['english_name']
        product.description = data['description']
        product.is_new = data['is_new']
        product.category = category
        product.save()
        return JsonResponse({'message': 'SUCCESS'}, status=201)

그리고 DB에는 아래의 정보가 이미 들어있다!

여기서 description만 수정하고 싶다면?

description딸기의 상큼함에서 스트로베리베리 상큼함으로 변경하려고 한다.

http -v POST localhost:8000/products/product/5 description="스트로베리베리 상큼함"

이렇게 하면 될 것 같지만, 서버는 500 에러를 뿜어내고 장렬히 전사한다.

KeyError가 났다고 하는데,
이유를 살펴보면 views.py 로직에서 작성한 모든 필드명을 보내주지 않아서 KeyError가 난 것이다.

그럼 try, except로 KeyError를 처리하면 되지 않을까?

class ProductDetailView(View): 
    def post(self, request, product_id):
        data = json.loads(request.body)
        try:
            category = Category.objects.get(name=data['category'])
            product = Product.objects.get(id=product_id)
            product.korean_name = data['korean_name']
            product.english_name = data['english_name']
            product.description = data['description']
            product.is_new = data['is_new']
            product.category = category
            product.save()
            return JsonResponse({'message': 'SUCCESS'}, status=201)
        except KeyError:
            return JsonResponse({'message':'INVALID_KEYS'}, status=400)

이렇게 로직을 변경하였다.

이제 KeyError가 나도 500에러를 뿜지 않고 INVALID_KEYS 메시지와 400에러가 뜰 것이다.

http -v POST localhost:8000/products/product/5 description="스트로베리베리 상큼함"

하지만 try, except는 500에러만 처리할 뿐 DB의 정보는 수정되지 않았다.
(description이 그대로 딸기의 상큼함이다.)

결국 로직에 작성한 모든 필드명을 넣어줘야 DB의 정보가 변경된다.

다시 말해 바꾸고 싶지 않은 필드인 korean_name, english_name, is_new, category까지 적어줘야 한다는 것이다.

http -v POST localhost:8000/products/product/5 korean_name="딸기 요거트 블렌디드" english_name="Strawberry Yogurt Blended" 
description="스트로베리베리 상큼함" is_new=0 category="블렌디드"

굳이굳이 다른 애들까지 다 적어서 보내주면 성공이다..!

DB에서도 잘 바꼈다.
(description스트로베리베리 상큼함으로 변경되었다.)

하지만 바꾸지 않을 필드명까지 적어야하는 게 번거롭다. 방법이 없을까?

당연히 있다.

바로 딕셔너리의 get 메소드를 이용하는 것이다!

딕셔너리.get(키, 기본값) : 딕셔너리 안에 찾으려는 Key 값이 없을 경우 기본값을 대신 가져온다.

product.korean_name = data['korean_name']
product.korean_name = data.get('korean_name', product.korean_name) 로 바꿔보았다.

1. 기존 로직

product.korean_name = data['korean_name']
프론트쪽에서 넘겨준 데이터(data)에서 키값이 korean_name인 값을 찾아 필드에 넣어주고, 만약 전달된 body에 korean_name이라는 키가 없으면 에러를 발생시켰다.

2. 변경된 로직

반면,
product.korean_name = data.get('korean_name', product.korean_name)
프론트쪽에서 넘겨준 데이터(data)에서 korean_name을 찾으면 넘겨주고, 만약 korean_name이라는 키가 없으면 기존에 있던 값인 product.korean_name을 사용하겠다는 의미이다.

class ProductDetailView(View): 
    def post(self, request, product_id):
        data = json.loads(request.body)
        category = Category.objects.get(name=data.get('category', product.category.name))
        product = Product.objects.get(id=product_id)
        product.korean_name = data.get('korean_name', product.korean_name)
        product.english_name = data.get('english_name', product.english_name)
        product.description = data.get('description', product.description)
        product.is_new = data.get('is_new', product.is_new)
        product.category = category
        product.save()
        return JsonResponse({'message': 'SUCCESS'}, status=201)
http -v POST localhost:8000/products/product/5 description="새콤달콤 신선한 딸기향 가득

description만 던져줘도 오류가 나지 않고 성공이라 뜬다!

실제 데이터베이스에서도 수정되었다!

이 방법은 이 유투브 영상을 참고하여 작성하였다. 더 자세히 알고 싶으면 영상을 참고하자.

profile
Leave your comfort zone
post-custom-banner

0개의 댓글