티스토리 뷰

Web/BackEnd

장고 REST API 정리

Hesh 2022. 8. 19. 01:39

 

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

 

Home - Django REST framework

 

www.django-rest-framework.org

역시 내가 나중에 써먹기 위해 정리

Models

from django.db import models

# Create your models here.
class Book(models.Model):
    bid = models.IntegerField(primary_key=True) # book id
    title = models.CharField(max_length=50) # book title
    author = models.CharField(max_length=50)
    category = models.CharField(max_length=50)
    pages = models.IntegerField()
    price = models.IntegerField()
    published_date = models.DateField()
    description = models.TextField()

필요한 property들을 model에 우선 저장

 

Serializer

파이썬 데이터 객체 형태로 저장된 데이터를 JSON 형태로 만들어주는 Serializer

역으로 받아올 때는 JSON 파일을 파이썬 데이터 객체로 돌리는 Deserialize를 거쳐야한다.

from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = ['bid', 'title', 'author', 'category', 'pages', 'price', 'published_date', 'description']

원래 밑바닦부터 작성하면 겁나긴데 저렇게만 써줘도 된다.

 

API View

장고의 views.py에 작성해줘서 API를 사용할 수 있도록 하자.

두가지 방식이 있고 클래스 방식인 CBV 와 함수형 방식인 FBV가 있다.

 

CBV

# views.py

from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.generics import get_object_or_404
from .models import Book
from .serializer import BookSerializer

# 클래스를 이용하여 API 생성하기
class BooksAPI(APIView):
    def get(self, request):
        books = Book.objects.all()
        serializer = BookSerializer(books, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK) 
    def post(self, request):
        serializer = BookSerializer(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)

class BookAPI(APIView):
    def get(self, request, bid):
        book = get_object_or_404(Book, bid=bid)
        serializer = BookSerializer(book)
        return Response(serializer.data, status=status.HTTP_200_OK)

put과 delete 가 없긴한데 이정도로만 일단 참고

 

CBV의 경우 urlpattern은 다음과 같이 as_view()를 붙여야 한다.

# urls.py

from django.urls import path
from .views import BookAPI, BooksAPI

urlpatterns=[
    path("cbv/books/", BooksAPI.as_view()),
    path("cbv/book/<int:bid>/", BookAPI.as_view()),
]

 

FBV

# views.py

from rest_framework import status
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.generics import get_object_or_404
from .models import Book
from .serializer import BookSerializer

# 데코레이터를 이용하여 함수형태로 API 생성하기
@api_view(['GET'])
def HelloAPI(request):
    return Response("Hello World")

@api_view(['GET','POST'])
def booksAPI(request):
    if request.method == 'GET': # 데이터를 요청하는 경우
        books = Book.objects.all() # Book 모델에 있는 모든 자료를
        serializer = BookSerializer(books, many=True) # Serializer에 넣어서
        return Response(serializer.data, status=status.HTTP_200_OK) # 응답해주고 status는 HTTP_200_OK로 띄우자
    
    elif request.method == 'POST': # 데이터를 추가하는 경우
        serializer = BookSerializer(data=request.data) # 받은 데이터를 시리얼라이저에 넣고
        if serializer.is_valid(): # 유효하다면
            serializer.save() # 역시리얼라이즈를 진행하고 모델 시리얼라이저의 crate() 함수가 작동됨
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        
@api_view(['GET'])
def bookAPI(request, bid):
    book = get_object_or_404(Book, bid=bid) # book id가 bid인 데이터를 Book 모델에서 가져오고 없으면 404 에러
    serializer = BookSerializer(book)
    return Response(serializer.data, status=status.HTTP_200_OK)

FBV의 경우 CBV와 달리 as_view()를 안붙여도 되긴한다.

# urls.py

from django.urls import path, include
from .views import bookAPI, booksAPI

urlpatterns=[
    path("fbv/books/", booksAPI),
    path("fbv/book/<int:bid>/", bookAPI),
]

 

저렇게 쓰고나니 되게 코드가 난잡하다.

간단하게 줄여줄 수 있는 Mixin을 사용해보자

 

Mixin

# views.py
# Mixin을 이용하여 중복문 제거

from rest_framework import mixins
from .models import Book
from .serializer import BookSerializer

class BooksAPIMixins(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)
    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
    
class BookAPIMixins(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_field = 'bid' # Django 기본 모델의 pk가 아닌 bid가 pk이므로
    
    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)

url은 CBV 처럼 작성

 

# urls.py

from django.urls import path
from .views import BooksAPIMixins, BookAPIMixins

urlpatterns=[
    path("mixin/books/", BooksAPIMixins.as_view()),
    path("mixin/book/<int:bid>/", BookAPIMixins.as_view())
]

 

그런데 아직도 상속할 class가 참 많다.

Generics 를 통해 줄여보자

 

Generics

https://www.django-rest-framework.org/api-guide/generic-views/

 

Generic views - Django REST framework

 

www.django-rest-framework.org

# views.py
# Generics를 이용하여 상속문 줄이기

from rest_framework import generics
from .models import Book
from .serializer import BookSerializer

class BooksAPIGenerics(generics.ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

class BookAPIGenerics(generics.RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    lookup_field = 'bid'

 

출처 :&nbsp;https://testdriven.io/blog/drf-views-part-2/

Generics를 사용하면 상속문을 줄일 수 있다.

Url은 CBV와 완전히 일치

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

[MySQL] Foreign Key 설정 시 유의점  (0) 2021.12.12
[Node.js] Sequelize로 CRUD 작업 처리하기  (0) 2021.12.11
[MySQL] Create, Read, Update, Delete (CRUD)  (0) 2021.12.10
[MySQL] SQL table 생성 정리  (0) 2021.12.09
Node.js 시작  (0) 2021.12.04
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday