Python/Django

[Django] 간단한 REST API 서버 만들기4 - Class Based View에서 POST, GET, PUT, DELETE 구현

개발새발 2020. 2. 10. 18:28
반응형

진행순서

1. Class Based View인 APIView를 상속하여 UserView 뼈대 만들기

2. POST, GET, PUT, DELETE 함수 구현

 

1. Class Based View인 APIView를 상속하여 UserView 뼈대 만들기

api_user/views.py에서 APIView를 상속하여 user를 생성, 삭제, 수정, 읽기를 할 수 있는 Class를 만든다.

CBV인 APIView를 사용하는 이유는 get, post, update, delete가 클래스내에 함수로 나누어져 있어서 직관성이 좋다.

 

views.py의 UserView의 큰 그림은 아래와 같다. CRUD 함수들이 한 클래스안에 함수별로 나누어진다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import UserSerializer
from rest_framework import status
 
class UserView(APIView):
    """
    POST /user
    """
    def post(self, request):
        return Response("test ok", status=200)
 
    """
    GET /user
    GET /user/{user_id}
    """
    def get(self, request):
        return Response("test ok", status=200)
 
    """
    PUT /user/{user_id}
    """
    def put(self, request):
        return Response("test ok", status=200)
 
    """
    DELETE /user/{user_id}
    """
    def delete(self, request):
        return Response("test ok", status=200)
 
cs

다음으로 UserSerializer를 활용하여 POST, GET ,UPDATE, DELETE를 처리하는 함수를 구현한다.

 

2. POST, GET, PUT, DELETE 함수 구현

[POST 구현]

 

1) request객체가 들어오면 미리 준비된 serializer로 변환

2) serializer객체를 통해 DB(sqlite3)에 데이터 저장

3) 저장된 내용을 JSON형태로 response로 전달

 

post

1
2
3
4
5
6
7
8
9
10
11
12
    """
    POST /user
    """
    def post(self, request):
        user_serializer = UserSerializer(data=request.data) #Request의 data를 UserSerializer로 변환
 
        if user_serializer.is_valid():
            user_serializer.save() #UserSerializer의 유효성 검사를 한 뒤 DB에 저장
            return Response(user_serializer.data, status=status.HTTP_201_CREATED) #client에게 JSON response 전달
        else:
            return Response(user_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
 
cs

 

테스트 해보면 정상적으로 DB에 사용자의 정보가 저장된다.

DB에도 정상적으로 반영이 되어있다.

 

 

[GET 구현 - 모든 유저의 정보 읽기]

 

1) 전체 user에 대한 요청이오면 쿼리셋(QuerySet)을 통해 모든 User의 정보를 DB에서 읽어온다.

2) serializer객체를 통해 DB(sqlite3)에 데이터 저장

3) 저장된 내용을 JSON형태로 response로 전달

 

 

[GET 구현 - 특정 유저의 정보 읽기]

 

1) 특정 한명의 user(id가 n인)에 대한 요청이 오면 해당 id에 맞는 user 1명의 정보를 DB에서 읽어온다.

2) serializer객체를 통해 DB(sqlite3)에 데이터 저장

3) 저장된 내용을 JSON형태로 response로 전달

 

*user id가 URL에 함께 들어온다고 구현하면 ex) http://localhost:8000/users/{id}

아래와 같이 api_user/urls.py에 추가해줘야 한다. (보통 id 없이 토큰으로 처리)

1

2
3
4
urlpatterns = [
    path('', views.UserView.as_view()), #User에 관한 API를 처리하는 view로 Request를 넘김
    path('<int:user_id>', views.UserView.as_view()) #User pk id가 전달되는 경우
]
cs

 

GET 함수는 다음과 같이 구현하면 된다.

1
2
3
4
5
6
7
8
9
10
    def get(self, request,  **kwargs):
        if kwargs.get('user_id'is None:
            user_queryset = User.objects.all() #모든 User의 정보를 불러온다.
            user_queryset_serializer = UserSerializer(user_queryset, many=True)
            return Response(user_queryset_serializer.data, status=status.HTTP_200_OK)
        else:
            user_id = kwargs.get('user_id')
            user_serializer = UserSerializer(User.objects.get(id=user_id)) #id에 해당하는 User의 정보를 불러온다
            return Response(user_serializer.data, status=status.HTTP_200_OK)
 
cs

 

http://localhost:8000/users 로 GET 요청 시 결과

[
    {
        "id": 2,
        "user_id": "abc",
        "password": "123",
        "address": null
    },
    {
        "id": 3,
        "user_id": "abc",
        "password": "123",
        "address": null
    },
    {
        "id": 4,
        "user_id": "abc",
        "password": "123",
        "address": null
    },
    {
        "id": 5,
        "user_id": "test_id",
        "password": "123",
        "address": "Seoul Korea"
    }
]

 

http://localhost:8000/users/5 로 GET 요청 시 결과

http://localhost:8000/users/5 로 GET 요청 시 결과

{
    "id": 5,
    "user_id": "test_id",
    "password": "123",
    "address": "Seoul Korea"
}

 

[PUT 구현]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    """
    PUT /user/{user_id}
    """
    def put(self, request, **kwargs):
        if kwargs.get('user_id'is None:
            return Response("invalid request", status=status.HTTP_400_BAD_REQUEST)
        else:
            user_id = kwargs.get('user_id')
            user_object = User.objects.get(id=user_id)
 
            update_user_serializer = UserSerializer(user_object, data=request.data)
            if update_user_serializer.is_valid():
                update_user_serializer.save()
                return Response(update_user_serializer.data, status=status.HTTP_200_OK)
            else:
                return Response("invalid request", status=status.HTTP_400_BAD_REQUEST)
 
cs

 

[DELETE 구현]

1
2
3
4
5
6
7
8
9
10
11
12
13
   """
    DELETE /user/{user_id}
    """
    def delete(self, request, **kwargs):
        if kwargs.get('user_id'is None:
            return Response("invalid request", status=status.HTTP_400_BAD_REQUEST)
        else:
            user_id = kwargs.get('user_id')
            user_object = User.objects.get(id=user_id)
            user_object.delete()
            return Response("test ok", status=status.HTTP_200_OK)
 
 
cs
반응형