urls.py에서 url을 설정하고, view 단에서 논리적인 구성을 하는 것은 일반 Django와 똑같습니다.
우선 대강 url 구성먼저 합시다. GET api/v1/rooms/list를 날리면 모든 방을 json 형태로 반환할 것입니다.
# config/urls.py
urlpatterns = [
path("admin/", admin.site.urls),
path("api/v1/rooms/", include("rooms.urls")),
]
# rooms/urls.py
urlpatterns = [path("list", views.list_rooms)]
이제 views.py에서 로직을 작성해주면 됩니다.
🚀 serializers (직렬화) : json 만들기
python에서 하듯 json 모듈을 써서 dump 메서드로 json을 만드는 방법은 안 통합니다.
쿼리셋이나 특정 타입을 JSON으로 곧장 변환시킬 수 없습니다. 아래 코드를 실행한다면 TypeError : Object of type Room is not JSON serializable 를 냅니다.
rooms = Room.objects.all()
rooms_json = []
for room in rooms:
rooms_json.append(json.dumps(room))
response = HttpResponse(content=rooms_json)
다음과 같이 django.core의 serializers를 사용해서 쿼리셋을 json화 해준 후 HttpResponse에 담아서 리턴해야 json을 받을 수 있습니다. 물론 이 방법은 잘 작동하지만 데이터에 대한 validation을 하지 않는다는 단점이 있습니다.
from django.core import serializers
from django.http import HttpResponse
from rooms.models import Room
# Create your views here.
def list_rooms(request):
rooms = Room.objects.all()
data = serializers.serialize("json", rooms)
response = HttpResponse(content=data)
return response
🚀 DRF의 serializers
그러나 더 좋은 것은 DRF의 serializers를 사용하는 것입니다.
rooms 앱 내에 serializers.py 생성
Serializer의 내부에는 해당 api에서 보여주고 싶은 필드만 model에서 빼와서 활용하면 됩니다. 앞서 말한 validation이 이 serializer를 거쳐가며 이루어집니다.
# rooms/seiralizers.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()
@app_view를 활용한 뷰 모델 작성
#rooms/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from . import models as rooms_models
from .serializers import RoomSerializer
# GET 방식만 받도록 함
@api_view(["GET"])
def list_rooms(request):
rooms = rooms_models.Room.objects.all()
# many=True의 역할은 rooms가 여러 값으로 이루어진 것이라는 것을 Serializer에게 알려주는 것
serialized_rooms = RoomSerializer(rooms, many=True)
# HttpResponse가 아니라 DRF의 Response를 씁시다.
return Response(data=serialized_rooms.data)
허허 잘 나옵니다.
🚀 serializers 추가 내용
serializers.py를 위와 같이 모델에서 일일히 따올 필요 없이, 다음과 같이 ModelSerializer를 상속 받은 후에 Meta 클래스를 통해서 작성할 수도 있습니다.
from rest_framework import serializers
from . import models as rooms_models
class RoomSerializer(serializers.ModelSerializer):
class Meta:
model = rooms_models.Room
fields = (
"name",
"price",
"bedrooms",
"instant_book",
)
관계가 설정된 필드를 가져올 때 단순히 해당 필드만 가져오면 키값만 표시합니다.
필드를 또 다른 serializer로 구성하면 관련 내용이 보여지게 됩니다.
user와 관련해서 Serializer를 하나 만들고 이를 다른 Serializer의 필드로 넣어주었습니다.
# users/serializer.py
from rest_framework import serializers
from . import models as users_models
class TinyUserSerializer(serializers.ModelSerializer):
class Meta:
model = users_models.User
fields = (
"username",
"superhost",
)
# rooms/serializer.py
from rest_framework import serializers
from . import models as rooms_models
from users.serializers import TinyUserSerializer
class RoomSerializer(serializers.ModelSerializer):
user = TinyUserSerializer()
class Meta:
model = rooms_models.Room
fields = ("name", "price", "bedrooms", "instant_book", "user")
이제 user 필드 내부에 username과 superhost가 보여지게 됩니다.
'Django, Flask > 🔫 Django REST framework (DRF)' 카테고리의 다른 글
DRF ViewSet : ModelViewSet로 ViewSet 맛보기 (0) | 2020.06.16 |
---|---|
pagination (0) | 2020.06.16 |
DRF class based view : GenericView (0) | 2020.06.16 |
REST API 설계 원칙 (0) | 2020.06.16 |