drf
에서 기존에 사용하던 함수 형식 view를 클래스 형식 view CBV
로 고칠 때, urls.py
에 써주는 방식이 기존이랑 조금 달라진다.
#urls.py
urlpatterns = [
path('', views.ArticleList.as_view(), name='index'),
path('<int:article_id>/', views.ArticleDetail.as_view(), name='article_view')
]
이 as_view()
의 역할이 뭘까?
공식 문서에 따르면
ViewSet
이라는 단일 클래스 메서드가 뷰를 최종화하는 시점에서 해당 작업을 바인딩 할 수 있게 해주는 것
이라고 한다 !
솔직히 뭔 소린지 하나도 모르겠어서 코드를 직접 뜯어봤다.
#drf 하위의 views.py
def as_view(cls, **initkwargs):
"""
Store the original class on the view function.
This allows us to discover information about the view when we do URL
reverse lookups. Used for breadcrumb generation.
"""
if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
def force_evaluation():
raise RuntimeError(
'Do not evaluate the `.queryset` attribute directly, '
'as the result will be cached and reused between requests. '
'Use `.all()` or call `.get_queryset()` instead.'
)
cls.queryset._fetch_all = force_evaluation
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
대충 함수 형태가 이렇다.
설명을 읽어보면
우리가
URL reverse lookups
를 할 때 뷰에 대한 정보를 발견할 수 있게 함
이라고 적혀있다.
그러니까 as_view는
1. 뷰클래스의 초기화와 핸들러를 반환하는 기능을 제공
2. View 함수를 생성하고, 상속을 통해 여러 기능들을 믹스인
한다고 생각하면 된다!
좀 더 간단하게 말하자면, 걍 CBV를 사용하기 위해 as_view()
함수를 반드시 불러와야 한다고 생각하면 됨!
swagger에서 POST
형식을 사용할 수 있게 해주는 메소드다.
#views.py
# swagger_auto_schema 불러오기
from drf_yasg.utils import swagger_auto_schema
# 원하는 함수 위에 decorator를 붇여주기
class ArticleList(APIView):
~~~
@swagger_auto_schema(request_body=ArticleSerializer)
def post(self, request, format=None):
~~~
이런식으로 class
안의 함수 위에 직접 붙여주면 된다.
html
파일을 만든 뒤, !
를 입력하면 기본 형식이 자동 완성돼서 불러와진다!
front의 js
에서 코드를 작성하고 불러왔는데, 해당 오류가 뜨면서 문제가 잘 해결되지 않았다.
참고 링크
index.html
에서, body를 불러오기 전에 스크립트를 실행해서 생긴 오류라고 한다!
body 하위로 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>프론트엔드</title>
</head>
<body>
<h1>프론트엔드</h1>
<div id="articles"></div>
<!-- body 밑쪽에 js 배치 -->
<script src="index.js"></script>
</body>
</html>