_won_
wonprogrammer
_won_
전체 방문자
오늘
어제
  • 분류 전체보기
    • woncoding
      • TIL
      • WIL
    • source Code
      • Python
      • Programmers
      • BAEKJOON

블로그 메뉴

  • 방명록

티스토리

Github · Wonprogrammer
hELLO · Designed By 정상우.
_won_

wonprogrammer

TIL | 10.25.화 [Django : DRF]
woncoding/TIL

TIL | 10.25.화 [Django : DRF]

2022. 10. 25. 23:57

- 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 주소를 넣어준다.

GET 예시

 

POST 예시

 

 

 

 


 

 

 

[프로젝트에 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
    'woncoding/TIL' 카테고리의 다른 글
    • TIL | 10.27.목 [Django : DRF]
    • TIL | 10.26.수 [Django : DRF]
    • TIL | 10.24.월 [Django : DRF]
    • TIL | 10.21.금 [머신러닝 / Django]
    _won_
    _won_
    Coding Practice blog

    티스토리툴바