1. ModelViewSet 사용하기
장고에서 DRF를 사용하면 무려 코드 두줄로 기본 CRUD를 완성할 수 있다.
ModelViewSet 을 상속받아서, 쿼리셋과 Serializer만 설정해주면 된다.
그리고 라우터 한줄을 추가해주면 알아서 관련된 CRUD 엔드포인트를 만들어준다.
[Post 예시]
# views.py
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
# urls.py
router = DefaultRouter()
router.register('post', views.PostViewSet, basename='post')
urlpatterns= [
*router.urls,
]
위 코드의 PostViewSet 클래스는 ModelViewSet을 상속받아 구현되었고, 라우터를 통해 기본적인 CRUD 엔드포인트가 만들어졌다.
역할 | HTTP 요청 메소드 | 엔드포인트 |
게시물 리스트 출력 | GET | /post/ |
상세 게시물 출력 | GET | /post/{id} |
게시물 생성 | POST | /post/ |
게시물 업데이트 | Put,Petch | /post/{id} |
게시물 삭제 | DELETE | /post/{id} |
너무너무 간편하지만 안에 동작하는 코드들이 궁금해서 한번 짜보았다.
2. ViewSet 사용하기
ViewSet을 상속받으면 각 요청에 대한 응답을 직접 함수로 구현해서 커스텀해서 사용할 수 있다.
- get 요청 시
1) 전체 리스트 출력: many=True
2) 특정 아이템 출력: 쿼리셋 작성 시 get(pk=pk)
- post, put, petch
1) 아이템 생성시, serializer에 request.data 전달
2) 아이템 수정시 serializer에 수정할 게시물 객체와 request.data 함께 전달
3) 아이템 삭제 시 삭제할 아이템 객체.delete() 수행하면 바로 삭제됨
class PublicPostViewSet(ViewSet):
def list(self, request):
queryset = Post.objects.all()
serializer = PostSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self,request,pk=None):
qs = Post.objects.get(pk=pk)
serializer = PostSerializer(qs)
return Response(serializer.data)
def create(self, request):
serializer = PostSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def update(self,request, pk=None):
qs = Post.objects.all()
post = get_object_or_404(qs, pk=pk)
serializer = PostSerializer(post, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(serializer.errors,
status = status.HTTP_400_BAD_REQUEST)
def destroy(self, request, pk=None):
queryset = Post.objects.all()
post = get_object_or_404(queryset, pk=pk)
post.delete()
return Response({"message":"item deleted"}, status = 204)
3. ModelViewSet + aciton 데코레이터
이제 내부 동작을 어느정도 파악했으니, 간편하게 제공되는 ModelViewSet을 잘 활용해보자.
기본 CRUD 외에 기능을 구현하고 싶다면 action 데코레이터를 활용할 수 있다.
action 데코레이터에서 두가지를 설정해줄 수 있다.
1) detail: 특정 아이템에 대한 건지, 전체 아이템에 대한건지 -> /post/ or /post/{id}
2) methods = ['']: 어떤 Http 요청에 대한건지
그리고 아래 함수내에서 get_object() , get_serializer() 함수를 통해 클래스내의 object와 serializer를 간단하게 가져와서 함수내에서 사용할 수 있다.
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
@action(detail=False, methods=['GET'])
def public(self,request):
qs = self.queryset.filter(is_public=True)
serializer = self.get_serializer(qs, many=True)
return Response(serializer.data)
@action(detail=True, methods=['PATCH'])
def set_public(self, request, pk):
instance = self.get_object()
instance.is_public = True
instance.save()
serializer = self.get_serializer(instance)
return Response(serializer.data)
코드 해설
1. public
is_public=True 인 item만 출력
-> 기본 list 출력과 거의 동일한데, filter를 활용해주었다.
2. set_public
특정 아이템의 pulic 상태를 true로 업데이트 해주기
'Today I Learned > django' 카테고리의 다른 글
DRF APIView -> generic&mixin -> ViewSets 과정 차근 차근 알아보자 (1) | 2023.10.16 |
---|---|
requests.post() 로 tmap API 에 위치정보 POST해서 결과 받아오기 (1) | 2023.10.11 |
장고 django ManyToMany (N:M 다대다 관계) (0) | 2023.09.26 |
장고 django ForeignKey (1:N 관계) (0) | 2023.09.26 |
장고 (djagno) Rest framework tutorial #2 데이터 보내기(POST) (0) | 2023.09.11 |