본문으로 바로가기

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를 사용하는 것입니다.

 

Serializers - Django REST framework

 

www.django-rest-framework.org

 

 

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

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체