본문 바로가기
source-code/Django

Django Rest Framework _ @api_view 사용하기

by mattew4483 2021. 1. 21.
728x90
반응형

얼마 전 맛을 본 DRF.

그런데 뭐가 뭔지 전혀 모르겠었다! 정말 맛의 맛의 맛만 본 느낌.

오늘은 처음부터 차근차근 만들어 볼 예정.


1. 기본 환경 세팅

저번에 했던 거랑 똑같다!

Project와 App을 생성하고, pip install로 djagnorestframework도 설치!

settings.py

settings에 적어주는 걸 빼먹으면 안 된다! 이제는 말하면 입 아프다!

 

2. model 생성

models.py

뭐 정말 흔한 model이다.

 

3. Serializer 작성

저번에는 앱 자체를 Api라고 이름 붙였었다.

하지만 모든 앱을 그렇게 처리할 수는 없는 노릇.

따라서 기존 앱(여기서는 BlogApp)에 api라는 폴더를 만들고, 그 안에 serializers.py를 만들어준다!

 

serializers.py

역시나 저번에 했던 내용!

2021/01/19 - [django] - django REST framework 맛보기

 

django REST framework 맛보기

PNU Quiz앱을 만들기 위해 다른 개발자가 만든 퀴즈를 참고했었다. git clone을 받아 runserver를 돌려보니... 분명 완성된 코드인데, 이상한 화면밖에 보이지 않았다. 이게 무슨 일? 답답함을 해결하기

23life.tistory.com

여기서 Serializer 관련 부분을 참고하자!

 

4. view 작성

대망의 view 작성..!

views.py

필요한 건 요 정도. 많기도 하구만.

 

DRF에서 view를 처리할 땐 두 가지 선택이 가능하다.

함수형과 클래스형. 생각해보니 원래 django veiw에서도 이 둘을 선택할 수 있네?

함수형의 경우 api_view라는 데코레이터를, 클래스형의 경우 APIView라는 클래스를 상속받는다.

 

여기서는 함수형으로 작성!

...해보기 전에, REST API에 대해 조금만 더 알고 가보자.

 

REST API를 설계할 땐 반드시 지켜야 할 대원칙이 존재한다!

첫째, URL은 정보의 자원을 포함할 것.

둘째, 자원에 대한 행위는 HTTP Method(GET, POST, PUT, DELETE)로 표현할 것.

 

이게 무슨 소린고 하니...

요 두 가지 사례를 보자. 왼쪽은 post의 list를 보여주는, 오른쪽은 post를 지우는 URL요청이다.

이 중 REST를 적용한 url은? 당연히 위의 녀석들!

 

아항! 즉 RESTful 한 API란 URL에 행위를 직접 보여줘서는(showlist, delete 등) 안 된다!

URL에는 정보의 자원(posts, <int:pk>등)만을 보여주고, 행위는 HTTP method에 따라 결정돼야 하는 것!

 

그러면 요 HTTP method(GET, POST, PUT, DELETE)에 따라 무슨 행위를 하는디?

 

GET 요청 : 리소스 조회, 세부 정보 열람.

POST 요청 : 리소스 생성.

PUT 요청 : 해당 리소스 수정.

DELETE 요청 : 해당 리소스 삭제.

 

오호! 이제 똑같은 이름의 URL 요청이라도 method에 따라 다른 역할을 수행함을 알게 되었다!

 

이제 다시 view로 돌아가 함수형으로 REST API를 작성해보자.

views.py

제일 먼저 Read와 Create를 수행할 PostList함수!

 

함수형으로 view를 작성할 땐 @api_view(['method'])형태로 데코레이터를 붙여주면 된다!

즉 @api_view(['GET', 'POST'])를 통해 GET 요청과 POST요청이 들어올 때는 PostList함수를 작동시키는 것.

 

views.py

앞서 살펴본 것처럼, GET요청 → 리소스 조회 를 담당한다!

즉 request.method가 GET일 경우 우리가 만들어준 PostSerializer에 Post모델을 담아준다.

(PostSerializer(post, many=True)

 

여기서 many=True가 붙은 이유는? Post.objects.all()로 검색한 post는 list형태!

하지만 serializer는 한 개의 객체를 전제로 한다.

따라서 many=True를 추가해 중복 표현 값에 대한 list를 받을 수 있게끔 한 것!

 

이렇게 데이터가 전달된 serializer.data를 Response 하는데... 얘는 또 뭐람?

TemplateResponse의 일환으로 렌더링 되지 않은 콘텐츠를 가져오고,

클라이언트에게 반환할 올바른 컨텐츠 유형을 결정한다고 한다!

즉 마구잡이로 보낸 serializer.data를 각 목적에 맞게(여기선 GET 요청이니 리소스 조회!) 보여줄 수 있도록 하는 것!

 

views.py

elif를 통해 이번에는 POST 요청이 왔을 때 → 리소스 생성을 담당하도록!

PostSerializer에 request.data라는 녀석을 담아주는데... 얘는 또 뭐람?

 

이전 modelform을 작성했을 때 ModelForm(request.POST)란 녀석을 쓴 적이 있는데, 이와 유사하다고 보면 된다!

request.data는 DRF에서 제공하는데, 기존 HttpRequest를 확장해 더 유연한 요청을 제공한다고 한다.

(request.POST와 유사하지만 웹 API에 더 유용한 속성)

 

이렇게 받아온 POST 요청은? 반드시 유효성 검사를 거쳐야 한다!

.save()로 저장을 한 후 마찬가지로 Response를 보내주는데... status=201, 404와 같은 값이 붙어있다!

요놈들은 DRF에서 제공하는 HTTP 상태 코드! 

에러 종류에 따라(200, 300, 400, 500번대 에러) 다른 응답을 보내주므로 더욱 명시적이라고 할 수 있겠다.

 

views.py

와우. 이번에는 GET, PUT, DELETE 요청을 담당할 PostDetail 함수를 작성해보자.

 

views.py

우선 PostDetail 함수는 특정한 하나의 post에 해당하는 기능을 수행한다.

따라서 post를 특정할 수 있는 pk값을 받으며, 우선 try와 except를 통해 해당되는 post가 존재하는지 판단한다.

 

views.py

PostDetail 함수로 GET 요청이 왔을 때는? → 해당 post에 대한 세부 정보를 보여주도록!

 

views.py

PUT요청이 왔을 때는? → request 요청이 들어온 post를 serializer에 담아 유효성 검사 후 save!

 

views.py

DELETE요청이 왔을 때는? → 해당 post를 삭제!

 

5. urls 작성

기본적으로 Project의 url과 App의 url은 분리된 상태!

Project의 url은 include를 사용해 App.ulrs과 연결시켜주면 된다!

 

urls.py

이는 App의 urls.py!

url은 단 두 개. 구성 요소 역시 정보의 자원(posts, <int:pk>)뿐. 참으로 간단하다!

이것이 REST API의 힘!


자... 그럼 이게 대체 어떻게 동작하는지 살펴보자. 바로 runserver!

아차차차. 그전에 createsuperuser로 관리자 계정을 만든 후 로그인을 해주자.

url에 적은 주소에 맞춰 잘 접속을 하면...

 

http://127.0.0.1:8000/api/posts/

이런 화면이... 안 나올 거다!

저기 있는 hi 라는 post는 admin에서 미리 적어둔 녀석이다. 

즉 R이 잘 작동하는 중!

 

http://127.0.0.1:8000/api/posts/

밑으로 내려보면... 이렇게 POST 요청을 보낼 수 있도록 되어있다!

api/posts/ 란 url의 POST 요청은...? 맞다! 새로운 post를 생성하는 역할!

 

즉 여기에 데이터를 입력하면 새로운 post가 생성되는데...

이때 저 content칸에는 json형태로!!! 데이터를 보내야 한다!

(이를 설명해둔 블로그가 없었다... 덕분에 뭘 어떻게 해야 하는지 몰라 한참을 헤맸다)

아무튼 저런 식으로 POST 요청을 보내면...

 

http://127.0.0.1:8000/api/posts/

따란. 이렇게 C 도 잘 작동함을 볼 수 있다.

 

http://127.0.0.1:8000/api/posts/1/

특정 게시글 하나에 접근하고 싶다면? pk를 보내주면 된다!

posts/1 로 url 요청을 보내보니... 이렇게 세부 정보 페이지로 이동했다! D 기능 확인!

 

마찬가지로 json 형태로 PUT 요청을 보내면...

U 역시 잘 작동하고 있다!

 

마지막으로 빨간색 DELETE 버튼을 눌러보면...

D 역시 정상적으로 작동한다! 와우!

728x90
반응형