기록하는 개발자

[Django] REST API 본문

Web/Django

[Django] REST API

밍맹030 2020. 7. 20. 02:40
728x90

#REST Architecture

REST : REpresentational State Transfer

-http 를 이용해 통신하는 네트워크상에서 정한 약속

-분산 하이퍼미디어 시스템을 위한 소프트웨어 설계 형식

 

REpresentational : 자원을 대표하는 단어 또는 식별자를 통해

State Transfer : 자원의 상태를 전송하는 방법

즉, 자원을 이름으로 구분하여 상태를 전송하는 방법

 

REST 설계 조건 : REST가 되기 위한 필요충분조건

-서버와 클라이언트, STATELESS, 캐시, Uniform Interface, Layerd System, Code-On-Demand

 

#API : Application Program Interface

-Request, Response로 오가는 구조화된 데이터

 

#REST API

-REST 아키텍쳐 스타일을 따르는 API

-HTTP로 CRUD를 구현할 수 있는 API

 

*ViewSet이란 View(CRUD)를 설계하는 쉽고 간단한 방법

 

1. API View

from django.http import Http404

from rest_framework.views import APIView

from rest_framework.response import Response

from rest_framework import status

->import한 status를 바탕으로 response를 직접 만들어 보낸다.

 

class OOO(APIView):

   def<내가 필요로 하는 http method>:

           그 http method로 어떻게 처리할지는 직접 정의하기.

 

직접 Response와 status를 import하므로써 어떤 식으로 status를 받고 response를 어떻게 보낼 지를 내가 결정하는 것

 

#APIView_views.py
from post.models import Post
from post.serializer import PostSerializer
#status에 따라 직접 Response를 처리할 것
from django.http import Http404 #Get Object or 404 직접 구현
from rest_framework.response import Response 
from rest_framework import status 
#APIView를 상속받은 CBV
from rest_framework.views import APIView
#PostDetail 클래스의 get_object 메소드 대신 써도 됨
#from django.shortcuts import get_object_or_404

class PostList(APIView):
    def get(self, request):
        posts = Post.objects.all()
        #쿼리셋 넘기기(many=True인자)
        serializer = PostSerializer(posts, many=True)
        #직접 Response 리턴 해주기 : serializer.data
        return Response(serializer.data)

        def post(self, request):
            serializer = PostSerializer(data=request.data)
            if serializer.is_valid(): #직접 유효성 검사
                serializer.save()     #저장
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#PostList 클래스와는 달리 pk 값을 받음(메소드에 pk 인자)
class PostDetail(APIView):
    def get_object(self, pk):
        try:
            return Post.objects.get(pk=pk)
        except Post.DoesNotExist:
            return Http404
    
    def get(self, request, pk, format=None):
        post=self.get_object(pk)
        serializer = PostSerializer(post)
        return Response(serializer.data)

    def put(self, request, pk, format=None):
        post = self.get.objects(pk)
        serializer=PostSerializer(post, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk, format=None):
        post=self.get_object(pk)
        post.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

#mixins_views.py
from post.models import Post
from post.serializer import PostSerializer

from rest_framework import generics 
from rest_framework import mixins

class PostList(mixins.ListModelMixin, mixins.CreateModelMixin,
                generics.GenericAPIView):
    queryset = Post.objects.all() #쿼리셋 등록
    serializer_class = PostSerializer #serializer class 등록
    
    #list 메소드 내보내는 메소드
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    #create 내보내는 메소드
    def post(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

class PostDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                mixins.DestroyModelMixin, generics.GenericAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
    

#urls.py of APIView and minxins
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from post import views

#django rest framework -> router -> url
#rest framework는 라우터의 개념을 통해 url을 결정한다
#router=DefaultRouter()
#router.register('post', views.PostViewSet)

urlpatterns = [
    path('post/', views.PostList.as_view()),
    path('post/<int:pk>/', views.PostDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)

 

 

2. mixins

from rest_framwork import mixins

from rest_framework import generics

#mixins_views.py
from post.models import Post
from post.serializer import PostSerializer

from rest_framework import generics 
from rest_framework import mixins

class PostList(mixins.ListModelMixin, mixins.CreateModelMixin,
                generics.GenericAPIView):
    queryset = Post.objects.all() #쿼리셋 등록
    serializer_class = PostSerializer #serializer class 등록
    
    #list 메소드 내보내는 메소드
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    #create 내보내는 메소드
    def post(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

class PostDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
                mixins.DestroyModelMixin, generics.GenericAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
    
    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)
    

#urls.py of APIView and minxins
from django.urls import path, include
from rest_framework.urlpatterns import format_suffix_patterns
from post import views

#django rest framework -> router -> url
#rest framework는 라우터의 개념을 통해 url을 결정한다
#router=DefaultRouter()
#router.register('post', views.PostViewSet)

urlpatterns = [
    path('post/', views.PostList.as_view()),
    path('post/<int:pk>/', views.PostDetail.as_view()),
]
urlpatterns = format_suffix_patterns(urlpatterns)

3. ViewSet         

Import action(from decorators), Response(from response)

Permission_classes = [permissions.IsAuthentificatedOrReadOnly,IsOwnerOrReadOnly] → 권한 설정

 

@+함수들 → 장식자(action decorator)

Ex)

@action()

Def func() …

 

#ViewSet_views.py
from post.models import Post
from post.serializer import PostSerializer
from rest_framework import viewsets

# @action 처리
from rest_framework import renderers
from rest_framework.decorators import action
from django.http import HttpResponse

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

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

    # @action(method = ['post'])
    @action(detail=True, renderer_classes=[renderers.StaticHTMLRenderer])
    #'얍'을 띄우는 custom api
    def highlight(self, request, *args, **kwargs):
        return HttpResponse("얍")

#urls.py for ViewSet
from rest_framework.routers import DefaultRouter
from django.urls import path, include
from post import views

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

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

 

*Color Scripter 클립보드 복사하면 예쁘게 코드 떴었는데

왜 요새 계속 그냥 HTML 복사하기 처럼 주소 복사되는지 모르겠다...

(티스토리 코드 올라가는거 너무 구려,,,)

아시는 분 댓글 달아주세요..plz..

728x90

'Web > Django' 카테고리의 다른 글

[Django] Template 상속  (0) 2021.05.27
[Django] 초기 환경설정 재정리  (0) 2021.05.11
[Django] 내가 보려고 하는 정리  (0) 2020.07.20
[Django] Wordcount 프로그램  (0) 2020.05.16
[Django] 설치 및 가상 환경 실행  (0) 2020.05.16