[drf]airbnb-api - 5 APIView

Hyeseong·2021년 3월 24일
1

들어가기 앞서

APIView vs generic view

APIView의 경우 커스텀 로직을 가질 경우 사용하기 좋으며,(실제로는 API뷰는 꽤 많이 사용함)
generic view의 경우에는 이미 DRF에서 만들어 놓은 사항을 끌어와서 접착 시키면 좋은 녀석입니다.

ListAPIView는 실제 3줄만 작성하고 이전 FBV와 비교하면 혁신적이다. 혹은 개발자가 아니라도 짜겟네!라는 소리까지 들을 수 있을정도조.

APIView

rooms/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import ListAPIView
from .models import Room
from .serializers import RoomSerializer


class ListRoomsView(APIView):
	def get(self,request)
    	rooms = Room.objects.all()
    	serializer = RoomSerializer(rooms, many=True)
    	return Response(serializer.data)
    

rooms/urls.py

from django.urls import path
from . import views

app_name = "rooms"

urlpatterns = [
	path("list/", views.ListRoomsView.as_view()) # CBV처러 만들때 as_view() 작성하조?
    ]

post 요청

post 메서드를 선언만 했어도 멋진 폼 형식이 만들어졌습니다.

rooms/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.generics import ListAPIView
from .models import Room
from .serializers import RoomSerializer


class ListRoomsView(APIView):
    def post(self, request):
    	pass
    

즉, APIView를 상속 받아서 CRUD구현을 get, post, delete, put 등 직관적으로 바로바로 구현하는 편의성을 제공해서 이 클래스가 좋은점을 가지고 있는거조.

인증 인가를 APIView에서

공식 문서에는 아래와 같이 하라고 나오네요.
이 정도만 확인하고 다음에 더 짚고 넘어갈게요.g


ListAPIView

generics 모듈에 있는 ListAPIView클래스를 활용하면 APIView보다 더 손쉽게 작성할 수 있어요.
아래 두개 변수가 필수적으로 정의만 해도 기본적인 기능 구현은 가능해요.
generics를 이용하면 이미 정의된 클래스들을 끌어다 쓰는거에요. 즉 커스터마이징할 필요가 없을때의 뷰라고 생각하면되요. 인증 필요업구, 논리적인 것도 필요 없구 시간을 세이빙하기 좋은 케이스입니다.

  • queyrset class변수를 정의
  • serializer_class class변수를 정의

rooms/views.py

from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.generics import ListAPIView
from .models import Room
from .serializers import RoomSerializer


class ListRoomsView(ListAPIView):

    queryset = Room.objects.all()
    serializer_class = RoomSerializer

rooms/urls.py

from django.urls import path
from . import views

app_name = "rooms"

urlpatterns = [
	path("list/", views.ListRoomsView.as_view())
    ]

config/settings.py

하지만 한번에 모든 collections을 다 보여주는것은 바람직하지 않기에 이미 만들어진 페이지네이션 기능을 사용해보조. 특히 generics을 사용할 때 바람직하게 쓰일수 있어요.
여기서는 PageNumberPagination클래스를 사용합니다.

AUTH_USER_MODEL = "users.User"


# Django Rest Framework

REST_FRAMEWORK = {
    "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
    "PAGE_SIZE": 10,
}

만약 전체 API에 적용하기 보다 개별 API에 다르게 page_size 볼륨을 갖게 하고 싶다면 아래와 같이 스타일링하여 줄수 있어요. 별도의 커스터마이징한 페이지넘버클래스를 선언 -> 뷰클래스에 상속
그리고 상속받은 클래스에는 pagination_class라는 클래스 변수를 오버라이딩하여 커스터마이징한 클래스를 값으로 갖게하면 됩니다~(아래 공식 문서 참조)


SeeRoomView

앞서서 봤던것들은 DB의 테이블의 로우들을 몇개씩 나타낼지 확인했다면 이제는 한개! 로우의 구체적인 컬럼 정보를 나타내는 영역이라고 보면되요.
좀 쉽게 표현하면 ProductDetailView를 표현하는 영역입니다.

이번에도 generics 모듈안의 클래스중 하나인 RetrieveAPIView를 사용해서 만들어 볼게요.
ListRoomsViews클래스 안의 클래스변수와 마찬가지로 두가지변수를 정의해주면 되요.
queryset, serializer_class이조.

새로 임포트된 RetrieveAPIView는 여기서는 방하나의 정보를 보여주기 위해 사용되는 generic APIView이고, BigRoomSerializer는 직접 ModelSerializer를 상속받아 작성해줘야하는 부분이에요.

rooms/views.py

from rest_framework.generics import ListAPIView, RetrieveAPIView
from .models import Room
from .serializers import RoomSerializer, BigRoomSerializer

...
...
...

class SeeRoomView(RetrieveAPIView):

    queryset = Room.objects.all()
    serializer_class = BigRoomSerializer

url지정을 아래와 같이 가볍게 해줍니다.

rooms/urls.py

from django.urls import path
from . import views

app_name = "rooms"

urlpatterns = [
    path("list/", views.ListRoomsView.as_view()),
    path("<int:pk>/", views.SeeRoomView.as_view()),
]

구체적인 방 하나!의 정보를 확인하기 위해서 메타클래스 변수인 fields에 pk를 추가하여 클라이언트에 정보를 던져줄 수 있도록 합니다.

serializer 정의

from rest_framework import serializers
from users.serializers import TinyUserSerializer
from .models import Room


class RoomSerializer(serializers.ModelSerializer):
    user = TinyUserSerializer()

    class Meta:
        model = Room
        fields = ("pk", "name", "price", "instant_book", "user")


class BigRoomSerializer(serializers.ModelSerializer):
    class Meta:
        model = Room
        exclude = ()

lookup_url_kwarg

참고로 url parameter를 작성할 때 매번 동일하게 pk라고 작성하기보다 다른 키를 먹이고 싶을떄?
lookup_url_kwarg를 view클래스의 변수로 선언하고 본인이 변경하길 원하는 것으로 바꾸면됩니다.

urls.py

path("<int:pkkk>/", views.SeeRoomView.as_view()),

views.py

class SeeRoomView(RetrieveAPIView):
...
lookup_url_kwarg = 'pkkk'

profile
어제보다 오늘 그리고 오늘 보다 내일...

0개의 댓글