JSON 응답뷰 만들기

최동혁·2022년 12월 6일
0

DRF

목록 보기
2/19

JSON 응답뷰 만들기

한 Post 모델에 대한 API 서비스를 제공할 때

이에 대한 URL을 설계한다면?

  1. 새 포스팅 내용을 받아 등록하고, 확인 응답 → /post/new/ 주소로 POST 요청
  2. 포스팅 목록 및 검색 응답 → /post/ 주소로 GET 요청
  3. 10번 포스팅 내용 응답 → /post/10/ 주소로 GET 요청
  4. 10번 포스팅 내용 갱신하고, 확인 응답 → /post/10/update/ 주소로 POST 요청
  5. 10번 포스팅 내용 삭제하고, 확인 응답 → /post/10/delete/ 주소로 POST 요청

REST API 스타일로 재설계

/post/ 주소

  • GET 방식 요청 : 목록 응답
  • POST 방식 요청 : 새 글 생성하고, 확인 응답
  • (사용 X) PUT/PATCH 방식 요청
  • (사용 X) DELETE 방식 요청

/post/10/ 주소

  • GET 방식 요청 : 10번 글 내용 응답
  • (사용 X) POST 방식 요청
  • PUT 방식 요청 : 10번 글 수정/저장하고, 확인 응답
  • DELETE 방식 요청 : 10번 글 삭제하고, 확인 응답

Django에서의 Post API

컨셉코드 (1/3)

# myapp/models.py

from django.db import models

class Post(models.Model):
		message = models.TextField()

# myapp/forms.py

from django import forms

class PostForm(forms.ModelForm):
		class Meta:
				model = Post
				fields = '__all__'

컨셉코드 (2/3)

/post/ 주소 (POST, GET)

# myapp/views.py

def post_list(request):
		if request.method == 'POST’:
				# 새 글 저장을 구현
				form = PostForm(request.POST, request.FILES)
				if form.is_valid():
						post = form.save()
						return JsonResponse(post)
				return JsonResponse(form.errors)
		else:
				# 목록 응답을 구현
				return JsonResponse(Post.objects.all())

컨셉코드 (3/3)

/post/10/ 주소 (PUT, DELETE, GET)

def post_detail(request, pk):
		post = get_object_or_404(Post, pk=pk)

		if request.method == 'PUT’:
				# 특정 글 갱신을 구현
				put_data = QueryDict(request.body)
				form = PostForm(put_data, instance=post)
				if form.is_valid():
						post = form.save()
						return JsonResponse(post)
				return JsonResponse(form.errors)

		elif request.method == 'DELETE’:
				# 특정 글 삭제를 구현
				post.delete()
				return HttpResponse()

		else:
				# 특정 글 내용 응답을 구현
				return JsonResponse(post)

DRF 설치

설치 : pip install djangorestframework~=3.11.0 (2020년 2월 현재 최신버전)

settings.INSTALLED_APPS에 "rest_framework" 추가

urlpatterns 다음 패턴 추가

urlpatterns = [
...
		path('api-auth/', include('rest_framework.urls'))
]

from django.conf.urls import url
from django.contrib.auth import views

app_name = 'rest_framework'

urlpatterns = [
		url(r'^login/$', views.LoginView.as_view(template_name='rest_framework/login.html'), name='login'),
		url(r'^logout/$', views.LogoutView.as_view(), name='logout'),
]
  • 여기서 api-auth 기능이 무엇이냐?
    • drf 상에서 최상위 페이지
    • 웹에서 바로 api 기능 테스트 해주는 페이지 지원

https://www.django-rest-framework.org/#installation

DRF에서의 Post API

Form/ModelForm → Serializer/ModelSerializer

FBV/CBV → FBV/CBV 그리고 ViewSet/ModelViewSet 등

컨셉코드 (1/3)

# myapp/models.py

from django.db import models

class Post(models.Model):
		message = models.TextField()

# myapp/serializers.py

from rest_framework import serializers
from .forms import Post

class PostSerializer(serializers.ModelSerializer):
		class Meta:
				model = Post
				fields = '__all__'

컨셉코드 (2/3)

/post/ 주소 (POST, GET)

/post/10/ 주소 (PUT, DELETE, GET)

# myapp/views.py

from rest_framework import viewsets

class PostViewSet(viewsets.ModelViewSet):
		queryset = Post.objects.all()
		serializer_class = PostSerializer

# myapp/urls.py

from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register('posts', views.PostViewSet)

urlpatterns = [
		path('', include(router.urls)),
]

router.register

  • 2개 URL을 만들어준다.

router.urls

  • url pattern의 list

다양한 HTTP 클라이언트 프로그램

유저가 웹브라우저를 통해 웹페이지 간 이동을 할 때

웹 프론트엔드에서 JavaScript를 통한 호출

Android/iOS 앱 코드를 통한 호출

웹 요청 개발 프로그램을 통한 호출

  • GUI 프로그램 : Postman → Powerful API Client
  • CLI 프로그램 : cURL, HTTPie
  • 라이브러리 : requests

HTTPie를 통한 HTTP 요청 방법 (1/2)

설치 : pip3 install httpie

HTTPie 명령 예시

> http GET 요청할주소 GET인자명==값 GET인자명==값
쉘> http --json POST 요청할주소 GET인자명==값 GET인자명==값 POST인자명=값 POST인자명=값
쉘> http --form POST 요청할주소 GET인자명==값 GET인자명==값 POST인자명=값 POST인자명=값
쉘> http PUT 요청할주소 GET인자명==값 GET인자명==값 PUT인자명=값 PUT인자명=값
쉘> http DELETE 요청할주소 GET인자명==값 GET인자명==

HTTPie를 통한 HTTP 요청 방법 (2/2)

2종류의 POST 요청 → 인코딩 방법의 차이

  • -form 옵션 지정 : multipart/form-data
  • -json 옵션을 지정하거나 생략 : application/json → 요청 데이터를 JSON 직렬화

httpbin.org 서비스를 통해, http 요청 연습을 해보자.

dispatch 함수 삽입

class PostViewSet(ModelViewSet):
		queryset = Post.objects.all()
		serializer_class = PostSerializer

		def dispatch(self, request, *args, **kwargs):
				print("request.body:", request.body)
				print("request.POST:", request.POST)
				return super().dispatch(request, *args, **kwargs)
  • 이렇게 설정을 해놓고 HTTPie를 이용해 게시글을 하나 생성한다면?
  • http POST http://localhost:8000/post/ message=”두번째 게시글”

  • 클라이언트 단에서 어떤 인코딩을 써서 보내는지는 적절히 상황에 맞춰서 쓰도록 하자.
  • json 형식으로 보내게 되면 request.POST에서는 읽을 수 없다.
  • 일반적으로 request.body를 읽어서 json.loads 해서 직렬화 해서 처리함.
  • —form 형식으로 보내면 POST에서도 읽을 수 있다.
profile
항상 성장하는 개발자 최동혁입니다.

0개의 댓글