Django를 활용하여 REST API 서버를 만드는 방법에 대해서 정리하기 위한 포스팅입니다.
개인적으로 사용하기 위한 것이라ㅠㅠ 정보 전달보다는 전체적으로 어떻게 학습 했는지를 봐주시면 좋을 것 같습니다.
공부했던 내용 순으로만 작성해보았습니다.
- Django restframwrok 설치
- https://www.django-rest-framework.org/#installation - api view 사용
- rest_framework.decorator api_view 를가지고와서
- @api_view를사용하면됨
- 예를들어@api_view(['GET', 'POST']) 이런식으로만들면 - Serializers를사용 ->Serializers.py 파일을 생성하여 이곳에 Serializer할 내용들을 입력
- serializer는Validation과다가능함
#serializers.py
from rest_framework import serializers
class RoomSerializer(serializers.Serializer):
name = serializers.CharField(max_length=140)
price = serializers.IntegerField()
bedrooms = serializers.IntegerField()
instant_book = serializers.BooleanField()
- Views.py에서 Serializer를 불러오기
#views.py
from .models import Room
from .serializers import RoomSerializer
@api_view(["GET","DELETE"])
def list_rooms(request):
rooms = Room.objects.all()
serialized_rooms = RoomSerializer(rooms, many=True)
return Response(data=serialized_rooms.data)
- Serializer에 ModelSerializer를 활용하면 더욱 간단하다.
- ModelSerializer를 상속받아오면 Meta Tag를 활용하여 원하는 필드의 값들만을 추출 할 수 있음.
- 근데 예제에서 아래의 User의 id 값을 얻고 싶은 것이 아닌 User의 username이나 권한등을 얻어오고 싶다면,
- TinyUserSerializer를 User App에서 Serialziers.py를 생성하여 값을 가져오면 된다.
#rooms/serializers.py
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 = ("name", "price", "instant_book", "user")
#users/serializers.py
from rest_framework import serializers
from .models import User
class TinyUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ("username", "superhost")
- Generic View를 활용해보자
- Generic View를 활용하면 더욱 간편하게 값들을 읽어 올 수 있다.
- view를 LisetAPIView를 활용해서 사용하기 위해서는 rest_framwork.generics > ListAPIView를 가져오고
#rooms/views.py
from rest_framework.generics import ListAPIView
from .models import Room
from .serializers import RoomSerializer
class ListRoomsView(ListAPIView):
queryset = Room.objects.all()
serializer_class = RoomSerializer
- ListView Pagenation하기
- ListView에서 모든 데이터를 가져오는 것이 아니라 원하는 갯수만큼만 보여주고 싶을 떄 사용하는 방법입니다.
- https://www.django-rest-framework.org/api-guide/pagination/
#settings.py
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination",
"PAGE_SIZE": 10,
}
https://www.cdrf.co/3.13/rest_framework.generics/ListAPIView.html
자세한 내용들을 위에 링크에 나와있습니다.
- DetailView API만들어보기
- ListVIew를 만든 이후에는 Detail View를 만들어 보도록 하면 됩니다.
- Detail View도 Generic에 RetrieveApiView를 활용하여 만들어 보면 됩니다.
#rooms/views.py
from rest_framework.generics import ListAPIView, RetrieveAPIView
from .models import Room
...
class SeeRoomView(RetrieveAPIView):
queryset = Room.objects.all()
serializer_class = BigRoomSerializer
#rooms/serializers.py
class BigRoomSerializer(serializers.ModelSerializer):
class Meta:
model = Room
exclude = ()
- 방금 했던 위의 내용들을 아주 간단히 하기위해서는 viewset이라는 것을 사용하면 아주 간단하게 사용할 수 있다!! viewset을 사용하는 방법은 restframworks에서 보면 되지만, 너무 간편해서 무섭다. 최대 큰 단점은 Viewset은 모든 것들을 한번에 제공해주기 때문에 보안적인 부분이 상당히 취약하다 -> 하지만 결국 Viewset으로 구축하면 너무 간편하다!
- POST를 사용하기 위해서는 먼저 FBV로 POST를 해보도록 하자
- 앞서 했던 것처럼 api_view Decorator를 활용해서 Function Based View로 만들어준 다음에 GET 방식과 POST방식으로 분기 처리를 해준다.
- 그리고 GET방식의 경우의 Serializer와 POST방식의 Serializer를 만들어 준다.
#rooms/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
...
@api_view(["GET", "POST"])
def rooms_view(request):
if request.method == "GET":
rooms = Room.objects.all()
serializer = ReadRoomSerializer(rooms, many=True).data
return Response(serializer)
elif request.method == "POST":
serializer = WriteRoomSerializer(data=request.data)
if serializer.is_valid():
return Response(status=status.HTTP_200_OK)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
WriteSerializer는 ModeilSerialzier말고 그냥 Serializer로 한번 가져와보자.
#rooms/serializers.py
class WriteRoomSerializer(serializers.Serializer):
name = serializers.CharField(max_length=140)
address = serializers.CharField(max_length=140)
price = serializers.IntegerField()
beds = serializers.IntegerField(default=1)
lat = serializers.DecimalField(max_digits=10, decimal_places=6)
lng = serializers.DecimalField(max_digits=10, decimal_places=6)
bedrooms = serializers.IntegerField(default=1)
bathrooms = serializers.IntegerField(default=1)
check_in = serializers.TimeField(default="00:00:00")
check_out = serializers.TimeField(default="00:00:00")
instant_book = serializers.BooleanField(default=False)
- POST 방식으로 Room 데이터를 추가 해보도록 합니다.
#rooms/serializers.py
class WriteRoomSerializer(serializers.Serializer):
name = serializers.CharField(max_length=140)
address = serializers.CharField(max_length=140)
price = serializers.IntegerField()
beds = serializers.IntegerField(default=1)
lat = serializers.DecimalField(max_digits=10, decimal_places=6)
lng = serializers.DecimalField(max_digits=10, decimal_places=6)
bedrooms = serializers.IntegerField(default=1)
bathrooms = serializers.IntegerField(default=1)
check_in = serializers.TimeField(default="00:00:00")
check_out = serializers.TimeField(default="00:00:00")
instant_book = serializers.BooleanField(default=False)
def create(self, validated_data):
return Room.objects.create(**validated_data)
@api_view(["GET", "POST"])
def rooms_view(request):
if request.method == "GET":
rooms = Room.objects.all()[:5]
serializer = ReadRoomSerializer(rooms, many=True).data
return Response(serializer)
elif request.method == "POST":
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(status=status.HTTP_400_BAD_REQUEST)
위의 코드를 보면 우선 POST 방식일 경우에 User의 인증 여부를 먼저 확인 한다음, is_valid()값이 참이면 serializer.save() 매서드를 호출하였습니다. create를 하지 않은 이유는 serializers는 바로 create, update함수를 직접 호출하는 것이 아닌 save매서드가 그 역할을 대신 수행해주기 때문입니다. 인자로 request.user instance를 넘겨주면 create함수에 validated_data에 자동으로 들어가게 됩니다.
그럼 다음 시간에는 방 디테일을 보는 것을 해보도록 하겠습니다.!
'프로그래밍 > Django개발(MAC OS)' 카테고리의 다른 글
Django Rest API 서버 만들기 요약 - Day 2 (0) | 2022.05.10 |
---|---|
Django Rest API 서버 만들기 요약 - Day 2 (0) | 2022.05.09 |
Django restframework 6. Create (0) | 2021.05.01 |
Django restframework 5. RetrieveAPIView (0) | 2021.04.24 |
Django restframework 4. ListAPIView (0) | 2021.04.24 |