티스토리 뷰
이 포스팅은 총 2단계로 이루어집니다.
👉 1단계 : HTTP Request를 잘받는 지 확인 + GET 요청에는 더미 JSON 주기
👉 2단계 : 실제 HTTP Method 동작을 하며 데이터를 건들이기
1단계
장고의 View 는 아래의 HTTP method를 받아줍니다.
그 중 GET, POST, PUT, DELETE 이 4가지를 받아보겠습니다.
우선 앱을 하나 만들어주겠습니다 :-)
저는 튜토리얼에서 만들었던 mysite 프로젝트에 앱을 추가할 것이고 rest_api_test 라는 이름으로 추가하겠습니다.
앱을 만들었으니까 프로젝트에 추가하는 작업을 해주겠습니다.
앱을 만들면 rest_api_test > apps.py 에 이런 코드가 자동으로 생겨있습니다.
mysite > settings.py에 가서 installed_app에 해당 앱을 추가해주세요 (맨아랫줄)
그 다음, mysite > urls.py에 가서 path를 추가해줍니다.
rest_api_test에는 urls 파일이 없으니까 urls.py 를 만들어주세요 그리고 아래와 같이 구현해주세요!+!
localhost:8000/rest_api_test/ 로 접속했을 때 IndexView 라는 것을 보여주겠다! 라고 해주는 코드입니다.
그럼 이제 아무 코드도 없는 views.py에 가서 IndexView를 만들어줍니다.
Get에 대한 응답만 더미 Json Reponse를 주도록 구현했습니다.
Get은 이렇게 웹브라우저에서 테스트 가능하지만,
다른 메소드들은 테스트하기 어려우니, API 테스트하는 툴로 유명한 Postman으로 테스트해보겠습니다 :-)
Postman으로 Get 요청 외에 데이터를 변경시키는 Post, Put, Delete 요청을 하려면
헤더에 csrf token값을 넘겨줘야합니다.
장고에서는 기본적으로 csrf 공격에 대해 대응을 하고 있기 때문입니다. 그래서 유효한 토큰인지를 확인하고 데이터를 추가하거나 변경시키려는 요청을 받아줍니다. 자세한 것을 여기 블로그 를 참고해주세요
그럼 csrf token을 어떻게 알 수 있을까요?!?
장고에 기본으로 설치되어있는 admin앱이 cookie로 csrftoken를 주는 로직이 있는 것 같습니다.
처음에 localhost:8000/admin로 접속하면 쿠키로 csrftoken를 줍니다.
처음 admin에 접속한 후에는 아무 주소로 장고서버에 접속하든 cookies로 csrftoken을 주더라구요 (그전에는 admin말고 다른 곳으로 접속하면 No cookie 였음)
localhost:8000/admin,
localhost:8000/polls,
localhost:8000/rest_api_test
이제 세 주소로 다 접속해도 쿠키로 csrftoken 값이 나오는 군요..!!
헤더에 이 값을 추가해야합니다...!! 키값은 X-CSRFToken 으로 하면 됩니다
이렇게 헤더를 추가해주세요
(⚠️ 만약 헤더에 csrftoken을 추가하지 않고 Get외의 요청을 하면 "Forbidden (CSRF cookie not set.)" 이라는 에러가 뜨니 꼭 추가해주세요 ⚠️)
그러면 Get 요청부터 해봅시다
Post요청도 잘 받고
Put 요청도 잘받고
Delete 요청도 잘 받네요
아 그리고 Get 요청빼고는 url뒤에 slash를 붙이지 않으면 이런 에러가 나오는데 Settings에 가서 설정해주면 slash 안붙여도 요청이 성공한다고 하네요...!! 저는 그냥 붙이고 하였습니다 : -)
You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to localhost:8000/rest_api_test/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings.
2단계
이제 각각의 HTTP Method 성격에 맞는 동작을 해줄 것입니다.
Post는 생성을 하도록, Put은 수정을 하도록, Delete는 삭제를 하도록 해줄게요...!!
그러기 위해 모델을 정의합니다.
모델을 만든 후, 두가지 명령어를 터미널에 실행시켜주세요
그 다음 IndexView의 코드를 변경 시켜줍니다.
함수 하나씩 살펴보겠습니다
1) GET
get 함수는 KakaoFriend DB에 있는 모든 데이터를 가져와서 최신 순으로 정렬합니다.
옛날 것부터 나오게 하려면 order_by('id') 라고 하면 됩니다.
저는 최신 데이터부터 나오게 하려고 order_by('- id') 라고 하였습니다.
그리고 모델들을 json으로 바꿔서 response를 줍니다
2) POST
request.META 를 사용해서 Content-type을 가져옵니다.
Content-type에 따라 분기를 한 이유는 Postman의 Body에 가서 form-data / x-www-form-urlencoded / raw > json 이 세가지로 모두
send 하고 Code를 눌러보시면 알 수 있습니다
2.1 form-data
2.2 x-www-form-urlencoded
2.3 raw > json
application/json인 content-type만 데이터 형식이 다른 것을 볼 수 있습니다.
HttpRequest.POST 문서를 보면 POST 요청이 왔을 때 content-type이 form-data 이나 x-www-form-urlencoded 라면
request.POST["name"] 이런식으로 request.POST 라는 QueryDic을 사용할 수 있지만,
content-type이 non-form 이라면 HttpRequest.body 를 통해 접근해라 라고 나와있습니다.
그래서 content-type 이 application/json인 것을 분기해서 body를 json으로 받아온 후 필요한 값들을 꺼내는 것입니다.
참고로 이 글을 읽어보면 요즘에는 application/json이 제일 많이 쓰인다고 하네요
3) POST 와 DELETE
장고에서 request.GET과 request.POST만 있고, request.PUT이나 request.DELETE는 없다고 하네요 😮
하지만 이것을 사용할 수 있는 방법을 맨 밑에서 소개하겠습니다--!!
그리고 POST와는 달리 PUT과 DELETE는 form-data나 x-www-form-urlencoded 의 content-type을 못받는 것 같아요
form 타입으로 요청하고 request.POST['name'] 로 값을 가져오려하면 해당 key값이 없다고 에러가 나더라구요
그래서 분기안하고 content-type이 application/json 인 것만 들어온다고 생각하였습니다.
그럼 잘 동작하는 지 테스트를 해보겠습니다
우선 GET을 요청해볼게요!! 아직 아무 데이터도 추가안했으니까 empty 배열을 잘 리턴해줍니다.
그 다음 Post 요청으로 모델 하나를 추가해보겠습니다
요청하면 200 OK 코드가 잘뜹니다.
다시 get을 해보면 추가한 죠르디가 잘들어가있습니다.
그리고 PUT 요청으로 죠르디의 나이를 5살에서 10살로 바꿔보겠습니다.
요청하면 200 OK 코드가 잘나옵니다.
그리고 다시 GET 요청하면 죠르디의 나이가 바뀌어있네요
그 다음, 죠르디를 지워줍시다.
200 코드로 성공하였습니다.
다시 GET요청해보면
죠르디가 지워지고 EMPTY 배열이 나오네요
마지막으로 form-data말고 raw > json으로 스카피를 추가해보고
x-www-form-urlencoded로 다시 죠르디를 추가해볼게요
성공코드가 잘 나오고 다시 GET 요청해보면 두개가 DB에 잘들어가있는 것을 볼 수 있습니다.
미들웨어를 추가하여 request.PUT과 request.DELETE를 쓸 수 있는 방법
이 블로그 를 참조하였습니다.
rest_api_test에 middlewares.py 파일을 만들고 위 블로그의 미들웨어 코드를 복사해주세요
mysite > settings.py에 가서 middleware를 추가해주세요 (맨마지막 줄)
이렇게 되어있었던 put함수를
아래와 같이 바꿔줄 수 있습니다!
이제 form-data과 x-www-form-urlencoded 타입으로 보내도 잘 받습니다.
(하지만 장고가 request.PUT과 request.DELETE를 안만든 이유가 분명히 있을 것 같아서 이 미들웨어를 저는 안쓸려구요..!)
PUT과 DELETE 모두 미들웨어로 구현하신 분의 블로그도 참조합니다 (근데 오래전 코드라서 에러가 남...ㅠㅠ)
'🐍 > Django' 카테고리의 다른 글
[Django] 튜토리얼 part 5 (1) - 테스트 작성하기 (0) | 2020.02.20 |
---|---|
[Django] Github User API를 사용하여 User 정보 보여주기 (0) | 2020.02.16 |
[Django] 튜토리얼 part 4 (2) - Generic view 사용하기 (0) | 2020.02.15 |
[Django] 튜토리얼 part 4 (1) - QueryDict (0) | 2020.02.15 |
[Django] 튜토리얼 part 3 (2) - 404 에러 일으키기, get_object_or_404, {% url %} 템플릿 태그 (0) | 2020.02.11 |
- Total
- Today
- Yesterday
- 장고 Custom Management Command
- flutter dynamic link
- Sketch 누끼
- Flutter Text Gradient
- 플러터 얼럿
- Dart Factory
- cocoapod
- drf custom error
- Flutter Spacer
- Python Type Hint
- METAL
- Flutter 로딩
- ribs
- flutter build mode
- flutter 앱 출시
- flutter deep link
- 플러터 싱글톤
- github actions
- Flutter Clipboard
- Django FCM
- DRF APIException
- Flutter getter setter
- ipad multitasking
- 구글 Geocoding API
- Django Heroku Scheduler
- Watch App for iOS App vs Watch App
- SerializerMethodField
- 장고 URL querystring
- Django Firebase Cloud Messaging
- PencilKit
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |