이전 포스팅에서는 스타벅스 제품을 생성하고, 조회하는 뷰를 작성하였다.
이번에는 특정 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()
로 삭제해주면 된다.