DRF(Django Rest Framework)(3) _ 클래스형 뷰(Class based View), 프론트엔드 출력하기
01. 클래스형 뷰(Class based view)
(※ 공식 문서 참고 링크)
- 클래스형 뷰로 변경했을 때에는 다른 클래스를 상속받을 수 있는 장점 등이 생긴다.
- 공식문서에 class view 기본 템플릿이 잘 나와있기 때문에 복사하여 일부만 수정하여 사용해도 괜찮다.
- 기존의 article_API view를 아래와 같이 클래스형 뷰로 변경한다.
# articles/views.py
...
class ArticleList(APIView):
def get(self, request, format=None):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request, format=None):
serializer = ArticleSerializer(data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
print(serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
- 클래스형 뷰를 사용하기 때문에 urls.py도 아래와 같이 변경해주어야 한다.
클래스형 뷰르 사용할 때에는 클래스뷰 이름 뒤에 .as_view()를 붙여주어야 한다.
from django.urls import path
from articles import views
urlpatterns = [
path('', views.ArticleList.as_view(), name='index'),
path('<int:article_id>/', views.article_detail_API, name='article_view'),
]
- 기존의 article_detail_API view도 마찬가지로 아래와 같이 클래스형 뷰로 변경한다.
# articles/views.py
class ArticleDetail(APIView):
def get(self, request, article_id, format=None):
article = get_object_or_404(Article,id=article_id) # 없는 값을 요청할 경우 404에러 발생
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)
else:
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)
- 마찬가지로 urls.py에서 해당되는 view의 url을 다시 지정해준다.
from django.urls import path
from articles import views
urlpatterns = [
path('', views.ArticleList.as_view(), name='index'),
path('<int:article_id>/', views.ArticleDetail.as_view(), name='article_view'),
]
02. Swagger 코드 보완
- post 함수에서 아래와 같이 swagger 데코레이션을 활용하여 swagger에서 API를 확인할 때 자세한 명세를 표기함과 동시에 API를 수정할 수 있도록 만든다.
# articles/views.py
from drf_yasg.utils import swagger_auto_schema
...
@swagger_auto_schema(request_body = ArticleSerializer) # swagger에 자세한 명세를 표기
def post(self, request, format=None):
serializer = ArticleSerializer(data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
print(serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
03. FrontEnd(html)에 출력하기
- Javascript에서 자체적으로 제공하는 Fetch API 사용하기 (※ 참고 링크)
- 프론트엔드 작업을 위한 별도의 폴더를 하나 더 생성하고 index.html, index.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>
<script src="index.js"></script> <!-- 자바스크립트 불러오기 -->
</head>
<body>
<h1>프론트엔드</h1>
<p>수정을 좀 하고</p>
</body>
</html>
console.log("자바스크립트를 불러왔습니다.")
// 로딩이 되자마자 동작할 것 : window.onload
// async function : 로드를 준비하는 동안 다른 동작을 보여준다.
window.onload = async function loadArticles(){
const response = await fetch('http://127.0.0.1:8000/articles/', {method:"GET"})
response_json = await response.json()
console.log(response_json)
}
- 이를 작성하고 템플릿을 실행해보면 아래와 같이 *CORS 오류메시지를 확인할 수 있다.
header를 살펴보면 cross-origin 정책이 'same-origin'이기 때문에 발생한 오류이다.
frontend : localhost:5500 / backend : 127.0.0.1:8000
*CORS : Origin(주소와 포트)이 다를 경우 보안을 위해 Access 허용을 받도록 하는 것
- 장고 App의 Header에 CORS에 대한 정보를 추가하여 어떻게 허용할지 설정한다. (※ 참고 링크)
- 먼저 아래와 같이 명령어를 실행하여 설치한다.
pip install django-cors-headers
- settings.py의 INSTALLED_APPS에 아래와 같이 추가한다.
INSTALLED_APPS = [
...,
"corsheaders",
...,
]
- settings.py의 MIDDLEWARE에도 아래를 추가한다. 여기서! 아래 코드의 윗부분 "corsheaders.middleware.CorsMiddleware"만 추가하는 것이며, 순서를 꼭 유의하여야 한다.
MIDDLEWARE = [
...,
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
...,
]
- 마지막으로 Configuration을 위해 아래 코드도 settings.py 마지막줄에 추가해준다.
CORS_ALLOW_ALL_ORIGINS = True
- 콘솔 창을 확인해보면 오류가 나타나지 않고 index.js가 실행되어 입력했던 데이터가 있음을 확인할 수 있다.
- 이제 코드를 화면에 그려보는 코드를 입력해본다.
- 먼저 html 파일에는 받아오는 데이터를 출력할 div를 아래와 같이 추가한다.
<!-- index.html -->
<!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>
<script src="index.js"></script> <!-- 자바스크립트 불러오기 -->
</head>
<body>
<h1>프론트엔드</h1>
<p>수정을 좀 하고</p>
<div id="articles"> <!-- 새로 받아온 데이터를 저장할 div -->
</div>
</body>
</html>
- index.js는 아래와 같이 코드를 추가한다.
// index.js
console.log("자바스크립트를 불러왔습니다.")
// 로딩이 되자마자 동작할 것 : window.onload
// async function : 로드를 준비하는 동안 다른 동작을 보여준다.
window.onload = async function loadArticles(){
const response = await fetch('http://127.0.0.1:8000/articles/', {method:"GET"})
response_json = await response.json()
console.log(response_json)
const articles = document.getElementById("articles")
//아래 코드는 for문처럼 동작된다.
response_json.forEach(element => {
const newArticle = document.createElement("div") // 하나의 div를 생성
newArticle.innerText = element.title // div안에 text는 title을 넣는다.
articles.appendChild(newArticle) // 메모리 상에 만들어져 있는 데이터를 실제 html에 넣는다.
});
}
- 위의 코드를 작성하고 새로고침하면 백엔드에 저장된 데이터를 프론트엔드 화면에 띄워주게 된다.
'DEV > Web 개발' 카테고리의 다른 글
Web 개발 :: Django 개발 중 소소하게 알게된 점 _ User_TIL#39 (0) | 2022.10.28 |
---|---|
Web 개발 :: 파이썬 Django Rest Framework(4) _로그인 방식 및 jwt 토큰 (0) | 2022.10.28 |
Web 개발 :: Django 머신러닝 프로젝트 Code Review _ User_TIL#37 (1) | 2022.10.26 |
Web 개발 :: 파이썬 Django Rest Framework(2) _ 포스트맨, Swagger (0) | 2022.10.26 |
Web 개발 :: Django 머신러닝 프로젝트 Code Review _ User_TIL#36 (0) | 2022.10.25 |
댓글