본문 바로가기
카테고리 없음

2) JSON 응답뷰 만들기

by 문자메일 2020. 5. 30.

한 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번 글 삭제하고, 확인 응답

 

컨셉 코드 (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)

#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)

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

settings.INSTALLED_APPS에 "rest_framework" 추가

urlpatterns 다음 패턴 추가

urlpatterns = [

    path('api-auth/', include('rest_framework.urls'))

]

 

 

from rest_framework.viewsets import ModelViewSet

from .serializers import PostSerializer

from .models import Post

 

class PostViewSet(ModelViewSet):

    queryset = Post.objects.all() # 2가지를 최소로 해주어야 한다. 데이터의 범위 지정 

    serializer_class = PostSerializer # Serializer class 지정

 

#위 ModelViewSet이 post_list의 2개 분기, post_detail 3개 분기 logic을 위 queryset과 serializer_class 2개의 정보만으로 지원을 한다는 의미이다.

 

http POST http://localhost:8000/post/ message="두번째 포스팅"

 

http POST http://localhost:8000/post/ message="두번째 포스팅"

http --form POST http://localhost:8000/post/ message="두번째 포스팅"

1.처럼 json 으로 보내게 되면 POST에서 담을 수 없다. 여러 depth로 구성될 수 있기 때문에

request body 자체를 읽어서 python 기본에 json.loads 를 통해 직렬화해서 처리를 한다.

2. 처럼 form data형식으로 보내게 되면 body가 form data형식으로 인코딩 되어 있고, request.POST에서도 위처럼 읽을 수 있다.

 

 

 

arg가 querystring이다.

 

http POST httpbin.org/post x=1 y=2

서버 body에"data" 부분 처럼 값이 넘어왔다는것을 볼 수 있음.

 

 

http --form POST httpbin.org/post x=1 y=2

form data라서 "form" 부분에 값이 찍혀 있는 것을 볼 수 있음

댓글