이전 포스팅에서는 스타벅스 제품을 생성하고, 조회하는 뷰를 작성하였다.
이번에는 특정 id의 product의 정보를 조회하고, 수정, 삭제하는 뷰, ProductDetailView를 작성해보도록 하겠다!
ProductView에 이미 product 정보를 조회하는 get 함수를 만들었는데, 또 만드는 이유는 무엇일까? 바로 전체 제품의 정보가 아니라 특정 id의 정보를 조회하고 싶기 때문이다!
그럼 조회하고 싶은 id 정보를 어떻게 받아올 수 있을까? request의 body에 넣어오는 방법도 있겠지만, get, delete는 body로 데이터를 전송하지 않는 것이 규칙이다. 그럼 어떻게 해야할까? 바로 url에 담아오면 된다!
class ProductDetailView(View):
def get(self, request, product_id): [1]
if not Product.objects.filter(id=product_id).exists():
return JsonResponse({'message': 'PRODUCT_DOES_NOT_EXIST'}, status=404)
product = Product.objects.get(id=product_id)
product_detail = {
'id' : product.id,
'korean_name' : product.korean_name,
'english_name' : product.english_name,
'description' : product.description,
'is_new' : product.is_new,
'allergy' : list(product.allergy.values('name'))
}
return JsonResponse({'data':product_detail}, status=200)
[1] : get 함수에 product_id를 받을 수 있는 파라미터를 지정해주었다.
product_id는 url로 받으니까 urls.py에 product_id를 받을 수 있는 경로를 지정해주자.
from django.urls import path
from .views import MenuView, CategoryView, ProductView, ProductDetailView
urlpatterns = [
...
path('/product/<int:product_id>', ProductDetailView.as_view()),
]
<>는 path 파라미터라고 하는데, 숫자, 문자열 모두 받을 수 있다. 이번에는 숫자를 받는다.
id가 1인 제품의 정보만 조회하고 싶다면 아래와 같이 Http 요청을 보내면 된다.
http -v GET 127.0.0.1:8000/products/product/1

def post(self, request, product_id):
data = json.loads(request.body)
if not Product.objects.filter(id=product_id).exists():
return JsonResponse({'message': 'PRODUCT_DOES_NOT_EXIST'}, status=404)
product = Product.objects.get(id=product_id)
category = Category.objects.get(name=data.get('category', product.category.name))
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)
이 로직에서는 KeyError를 따로 처리하지 않았다. 왜냐하면 딕셔너리의 get 메소드를 활용하여 내가 바꾸고 싶은 키값만 들어와도 처리가 가능하도록 했기 때문이다.
product.korean_name = data.get('korean_name', product.korean_name)
이런 식으로 키가 들어오지 않았을 경우에는 원래 있던 값을 사용한다.
이 포스팅에 더욱 자세한 설명을 해놓았으니 이해가 안 간다면 꼭 읽어보길 추천한다.
정보를 수정할 때는 어떤 HTTP 메소드를 사용해야 하나요?
정보를 수정할 때는 POST, PUT, PATCH 이 세 가지의 메소드를 모두 사용할 수 있다. 파고들어가면 각각의 메소드마다 차이는 있겠지만 현업에서는 그냥 POST로 수정 작업을 진행하는 경우가 많다. 보통 전체를 수정하는 경우는 없으므로,
ProductDetailView와 같이 상세정보를 관리하는 클래스를 새로 만들어post함수를 작성해주면 된다.
def delete(self, request, product_id):
if not Category.objects.filter(id=product_id).exists():
return JsonResponse({'message': 'PRODUCT_DOES_NOT_EXIST'}, status=404)
Category.objects.filter(id=product_id).delete()
return JsonResponse({'message': 'SUCCESS'}, status=200)
삭제하는 로직은 굉장히 간단하다. filter() 입력된 id에 해당되는 값을 찾아 delete()로 삭제해주면 된다.