Django Rest Framework
pip install djangorestframework
추가 설정
settings.py
LANGUAGE_CODE = 'ko-kr'
TIME_ZONE = 'Asia/Seoul'
JSON
일종의 딕셔너리로, 키값과 벨류값이 항상 TEXT형식인것과 차이가 있다.
Serializer
TEXT 형식을 JSON 형식으로 변환해준다.
DeSerializer
JSON 형식을 TEXT 형식으로 변환해준다.
from rest_framework import serializers
from .models import 모델이름
class Serializer(serializers.ModelSerializer):
class Meta:
model = 모델이름
fields = "__all__"
사용자 정의 모델 생성, Serializer 모델을 상속받아
모델과, 모든 필드를 적용했다.
import
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 Articles
from .serializers import SerializerArticle
from drf_yasg.utils import swagger_auto_schema
status
HTTP STATUS CODE를 반환하기 위한 패키지
Response
반환값을 보내주기위한 모듈
APIView
API 통신 관련 클래스가 정의되어 있으며, 개발자는 이 클래스를 상속받음으로써
오버라이딩 하여 재정의 할 수 있다.
get_object_or_404
이전까지 모델.objects.get(id=id)이러한 형태로 오브젝트를 탐색했는데
만약 탐색하는 값이 없으면 DoesNotExist에러를 띄웠기 때문에 별도의
try except문으로 제어해야 했다.
이 모듈은 이름 그대로 오브젝트를 반환받거나, 만약 값이 없다면 404 status code를 반환한다.
Articles
개발자가 정의한 모델, 구축한 데이터 베이스
SerializerArticle
개발자가 정의한 Serilizer 모델을 상속받은 커스텀 모델
swagger_auto_schema
개발환경에서 사용하는 API 명세서를 자동으로 반환해주며
POST방식의 경우, 별도의 데코레이터를 장식해주어야 한다.
class ArticleAPI(APIView):
def get(self, request, format=None):
articles_data = Articles.objects.all()
articles = SerializerArticle(articles_data, many=True)
return Response(articles.data)
@swagger_auto_schema(request_body=SerializerArticle)
def post(self, request, format=None):
serializer = SerializerArticle(data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data,status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
CBV 클래스 기반의 VIEW 함수를 작성했다.
ArticleAPI 클래스는 다음과 같이 구성했다.
GET : 모든 데이터 조회
POST : 게시글 작성
articles_data = Articles.objects.all()
articles = SerializerArticle(articles_data, many=True)
print(articles_data)
print(articles.data)
출력
<QuerySet [<Articles: 둘둘>]>
[OrderedDict([('id', 2), ('title', '둘둘'), ('comment', '둘둘'), ('create_at', '2023-04-18T17:03:55.400914+09:00'), ('update_at', '2023-04-18T17:03:55.400914+09:00')])]
출력을 보면 알 수 있듯이 쿼리셋을 JSON형태로 가공해준 것을 알 수 있다.
Serializer를 통해 JSON형태로 가공된 데이터를 뽑아내기위해서는
dot(.)data로 접속해야한다.
@swagger_auto_schema(request_body=SerializerArticle)
def post(self, request, format=None):
serializer = SerializerArticle(data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data,status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
POST 방식은 글쓰기 (CREATE) 기능으로 구현했으므로
GET(READ)와는 달리 JSON 형태를 OBJECT로 변환해야한다.
따라서 Serializer 모델을 이용해 DeSerializer를 이용하였고
is_valid는 호환성 검사를 자동으로 해준다.
status
글 작성후 성공적으로 됬는지 또는 어떠한 문제가 발생했는지에 관한
status code를 함께 반환한다.
상세 페이지
class ArticleDetail(APIView):
def get(self, request, article_id, format=None):
article = get_object_or_404(Articles,id=article_id)
serializer = SerializerArticle(article)
return Response(serializer.data)
def put(self, request, article_id, format=None):
article = get_object_or_404(Articles,id=article_id)
serializer = SerializerArticle(article,data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data,status=status.HTTP_200_OK)
else:
return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, article_id, format=None):
article = get_object_or_404(Articles, id=article_id)
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
window.onload = async function loadArticles() {
// async function : 비동기 라이브러리 동작을 시행하겠다.
const response = await fetch('http://127.0.0.1:8000/articles/', { method: 'GET' })
// await fetch, 백엔드와의 API 통신을 기다리겠다. 데이터가 모두 전달 완료가 될때까지 기다린다.
// GET 방식으로 Articles 모델의 데이터베이스 데이터를 모두 가져온다.
console.log("GET 실행 완료")
response_json = await response.json()
// 가져온 데이터를 JSON 형태로 가공되는것을 기다린다
console.log(response_json)
const articles = document.getElementById('articles')
response_json.forEach(index => {
console.log(index.title)
const newArticle = document.createElement("div")
newArticle.innerText = index.title
articles.appendChild(newArticle)
});
}
<javascript src ="함수이름..."></javascript>
async 비동기 프로그래밍 라이브러리
await fetch
코루틴 안에서 다른 코루틴의 실행의 완료를 기다린다.
즉 fetch의 실행 완료를 기다리는셈