[drf]airbnb api - 9 Room Detail GET


validation에 대해 우선 이야기 해볼게요.
django form과 비슷하게 작동하는게 이 validation이에요.

validation

FBV로 작성

아래 두가지 메서드를 구분해서 사용하는데요.

  • validate(self, validated_data)
  • validate_<field_name>(self,value)

rooms/serializers.py


def create(self,validated_data):
...
...

def validate_beds(self, beds):
	if beds < 5:
    	raise serializers.ValidationError('Your house is too small')
    else:
    	return beds

아래와 같이 요청을 한번 해볼게요.

이렇게 되면 베드가 4개이므로 raise serializers.ValidationError('Your house is too small') 오류가 발생하게 되요 --> 그리고 기존 if serializer.is_valid()에서 -> else문으로 넘어가 400에러를 뱉어내게되요.

다시 한번 정리하면 serializer.isvalid() -> validate() or validate필드이름() -> True, False에 따라 분기하여 200, 400로직을 처리

rooms/serializers.py

    def create(self, validated_data): 
        return Room.objects.create(**validated_data)

    def validate(self, data):  # 여기서 data는 request객체의 body부분을 의미
        check_in = data.get("check_in")
        check_out = data.get("check_out")
        if check_in == check_out:
            raise serializers.ValidationError("Not enough time between changes")
        else:
            return data # 만약  data를 리턴하지 않으면 create메서드의 validated_data에 None이 할당됨.

CBV로 만들기

준비물

  • APIView (get, post 메서드에 사용)
  • RetrieveAPIView(single item에 대한 get요청시 활용)

rooms/urls.py

# 생략
app_name = "rooms"

urlpatterns = [
    path("", views.RoomsView.as_view()),
    path("<int:pk>/", views.RoomView.as_view()),
]

rooms/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Room
from .serializers import ReadRoomSerializer, WriteRoomSerializer


class RoomsView(APIView):
    def get(self, request):
        rooms = Room.objects.all()[:5]
        serializer = ReadRoomSerializer(rooms, many=True).data
        return Response(serializer)

    def post(self, request):
        if not request.user.is_authenticated:
            return Response(status=status.HTTP_401_UNAUTHORIZED)
        serializer = WriteRoomSerializer(data=request.data)
        if serializer.is_valid():
        	room = serializer.save(user=request.user)
            room_serializer = ReadRoomSerializer(room).data
            return Response(data=room_serializer, status=status.HTTP_200_OK)
        else:
        	return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST) # serializer.erros는 유효성 검사시 raise된 오류를 띄워줍니다.


class RoomView(APIView):
    def get(self, request, pk):
        try:
            room = Room.objects.get(pk=pk)
            serializer = ReadRoomSerializer(room).data
            return Response(serializer)
        except Room.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)

    def put(self, request):
        pass

    def delete(self, request):
        pass

일부러 오류를 내기 위해서 url parameter의 pk값에 오류를 낼 수 있도록 값을 디비에 없을것 같은 값을 넣어주면되요.

좋은 웹페이지 즐겨찾기