- Django Rest Framework
DRF Tutorial
- DRF로 프로젝트 세팅
- 시리얼라이저 model 활용
- models에 정의된 objects들을 딕셔너리 형태 즉, JSON형태의 str으로 만들어 자동으로 response 할 수 있게 만들어 주는게 serializer 이다.
- 시리얼라이저를 활용해서 CRUD하기
- 포스트맨으로 DRF 개발을 테스팅
- 프로젝트에 Swagger를 적용하기
- swagger url 설정
- settings에 'django.contrib.staticfiles', 'drf_yasg' 설정
- 클래스형 뷰를 작성할 수 있다.
- 함수와 다르게 class는 추후에 다른 함수나 class의 상속이 가능하다.
- fetch api를 써서 프론트엔드에서 DRF의 데이터를 가져와서 나타낼 수 있다.
- front 폴더를 생성 및 html/js파일을 만들어 연동 후 백엔드에서 실행되고 있는 서버 주소와 연결해준다.
[DRF로 프로젝트 세팅]
모든 프로젝트는 먼저 model과 url작업을 먼저 해준다.
그 후 url을 실행시킬 method 별로 views.py 를 작업해준다.
- 기존의 pure django 에서 사용하던 templates를 사용하지 않고, rest_framework에서 api 브라우저에 직접 들어가서 조작 할 수 있게끔 만들어준다.
# api_view를 import 해준뒤
from rest_framework.decorators import api_view
# 어떤 method에 작업을 할건지 선언 해준다
@api_view(['GET', 'POST'])
def 함수
[serializer model 활용]
- 기존 방식으로 model에 저장된 데이터를 불러오려면
articles = Article.objects.all()
# 아래와 같이 딕셔너리를 하나하나 만들어 주면서 불러와야 한다.
article_date = {
'title':article.title,
'content':article.content,
'create_at':article.create_at,
'update_at':article.update_at,
}
👉 이렇게 되면 데이터를 불러올 때 마다 힘들기 때문에 이를 자동화 해주는 것이 serializer라고 할 수 있다.
- serializer model 선언
from dataclasses import field
from rest_framework import serializers
from articles.models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
# models.py 정의된 model 호출 (거기에 저장되는 objects 가져올거니까)
model = Article
# 모든 objects 가져올거니까 all
fields = '__all__'
↓
- serializer model 선언 후 views.py 정의
- GET(2) / PUT / DELETE
from articles.serializers import ArticleSerializer
# 모든 게시글을 가져오는 GET
articles = Article.objects.all()
# 불러온 articles를 serializers 시켜준다.
# many=True는 article 하나가 아닌 여러개이기 때문에 list 형태로 가져오기 위해 설정해준다.
serializer = ArticleSerializer(articles, many=True)
# Response는 쿼리, 딕셔너리 등 json에서 다룰 수 있는 데이터만 받는다. + serializers에 들어있는 데이터를 가져오기 위해선 '.data'를 붙여줘야 한다.
return Response(serializer.data)
from articles.serializers import ArticleSerializer
@api_view(['GET', 'PUT', 'DELETE'])
def articleDetailAPI(request, article_id):
# 특정 상황에서 해당 게시글만 가져오는 GET
if request.method == 'GET':
# list를 가져올땐 many속성이 필요하지만 아래 GET은 id가 같은 1개만 불러오기 때문에 필요없다.
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article)
return Response(serializer.data)
elif request.method == 'PUT':
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article, data = request.data) # 데이터를 수정한 데이터로 다시 받아와
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
elif request.method == 'DELETE':
article = get_object_or_404(Article, id=article_id)
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
- POST
from articles.serializers import ArticleSerializer
# POST된 데이터를 어떻게 모델에서 정의된 articles형태로 바꿔줄 것인가?
serializer = ArticleSerializer(data = request.data)
# 사용자가 작성한 게시글에 대한 유효성 검사 필요! (유효성 검사 후 저장)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
[Postman으로 DRF 개발을 테스팅]
- 1) collection 생성
- 2) Add a request

- 2-1) 생성된 requests를 사용하기 전 url 주소를 Enviroments 환경에서 미리 정의 해준다.

- 3) 각각의 Method에서 작동될 url 주소를 넣어준다.


[프로젝트에 Swagger를 적용하기]
- swagger 참고 링크
drf-yasg - Yet another Swagger generator — drf-yasg 1.20.1 documentation
Since the schema does not usually change during the lifetime of the django process, there is out of the box support for caching the schema view in-memory, with some sane defaults: caching is enabled by the cache_page decorator, using the default Django cac
drf-yasg.readthedocs.io
위 링크를 참고해 먼저
- 1) swagger를 적용하기 위해 필요한 패키지 설치
pip install drf-yasg
- 2) swagger settings.py 설정
INSTALLED_APPS = [
...
'django.contrib.staticfiles', # required for serving swagger ui's css/js files
'drf_yasg',
...
]
- 3) swagger urls.py 설정
# In Project main urls.py
...
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
...
schema_view = get_schema_view(
openapi.Info(
title="Snippets API",
default_version='v1',
description="Test description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="contact@snippets.local"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)
urlpatterns = [
내가 설정한 url 경로 +
re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
...
]
- 4) views.py 에서 swagger 적용하기
# swagger를 import해주면 : 정의된 method에 관한 '/swagger'를 볼 수 있다
from drf_yasg.utils import swagger_auto_schema
+
GET / PUT / DELETE 와 다르게 POST는 새롭게 데이터를 생성하는 method이기 때문에
@swagger_auto_schema(request_body=ArticleSerializer)
def post(self, request, format=None):
# @swagger_auto_schema로 우리가 json 형태로 작성 할 수 있게 만들어줘야한다.
[Class형 view 작성]
- 지금까지 배운 def 함수 형 view 정의에서
# class형 view는 아래와 같이 따로 @api_view를 선언할 필요 없이 class에 넣어 관리 할 수 있다.
@api_view(['GET', 'PUT', 'DELETE'])
def articleDetailAPI(request, article_id):
if request.method == 'GET':
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article)
return Response(serializer.data)
elif request.method == 'PUT':
.
.
elif request.method == 'DELETE':
.
.
# 또한, class는 상속에 자유로워 더욱 유용하게 사용할 수 있다.
↓
- class형 view로 재정의
from rest_framework.views import APIView
# @api_view 선언 필요없이 정의 할 수 있다.
class ArticleDetail(APIView):
def get(self, request, article_id, format=None):
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article)
return Response(serializer.data)
def put(self, request, article_id, format=None):
article = get_object_or_404(Article, id=article_id)
serializer = ArticleSerializer(article, 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)
def delete(self, request, article_id, format=None):
article = get_object_or_404(Article, id=article_id)
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
[Frontend]
fetch api를 이용해 백엔드에서 개발한 내용을 사용자가 다룰 수 있게 만들어 준다.
- 1) 새로운 front파일을 만들어 사용자에게 보여줄 .html 파일을 만들어 준 뒤 .js 파일을 넣어준다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend</title>
# 백엔드 서버를 가져올 .js 파일 선언
<script src="index.js"></script>
</head>
<body>
<h1>
Frontend
</h1>
<p>live server : Go live 누르면 자동 연결 + 수정시 자동 새로고침</p>
<div id="articles"></div>
</body>
</html>
- 2-1) 백엔드 서버를 불러올 .js 파일을 만들어 준다.
- 2-1-1) 불러오기 전, 다른 도메인에서 요청을 보낼땐 별도의 허용이 필요하다. 따라서 백엔드 서버에서 cors 허용해주기
- 2-1-2) pip install django-cors-headers
- 2-1-3) 허용한 cors → Insatalled App에 선언
- 2-1-4) MIDDLEWARE 에 'corsheaders.middleware.CorsMiddleware' 선언
- 2-1-5) 마지막에 추후 Domain에 적용하기 위해 → CORS_ALLOW_ALL_ORIGINS = True 추가해주기
1) pip install django-cors-headers
2) INSTALLED_APPS = ['corsheaders',]
3) MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', ← 이 문장 위에 추가 해줘야됨 !주의!
]
4) settings.py 에 "CORS_ALLOW_ALL_ORIGINS = True" 추가!!
- 2-2) 이후 .js 파일 작성
# 로딩이 되자마자 띄우기 = window.onload
window.onload = async function loadArticles(){
# 백엔드에서 가져올 서버 및 method 선언
const response = await fetch('http://127.0.0.1:8000/articles/', {method:'GET'})
// 시리얼라이즈되어 온 데이터를 우리가 쓰고 싶은 형태로 활용하기 위해서
response_json = await response.json()
// ID 하나씩 article 가져오기
const articles = document.getElementById("articles")
response_json.forEach(element => {
// .html 파일에 선언된 div='articles' 부분에 띄어준다
const newArticle = document.createElement("div")
newArticle.innerText = element.title
articles.appendChild(newArticle)
});
}
[참고 문서]
Home - Django REST framework
www.django-rest-framework.org
'woncoding > TIL' 카테고리의 다른 글
| TIL | 10.27.목 [Django : DRF] (0) | 2022.10.28 |
|---|---|
| TIL | 10.26.수 [Django : DRF] (0) | 2022.10.27 |
| TIL | 10.24.월 [Django : DRF] (0) | 2022.10.24 |
| TIL | 10.21.금 [머신러닝 / Django] (0) | 2022.10.24 |
| TIL | 10.20.목 [머신러닝 / Django] (0) | 2022.10.20 |