APIView
์ api_view
๋ ๊ฐ๊ฐ CBV์ FBV์ ๋์๋๋ ๋ด์ฉ/article/
์ ๋ํ CBV/article/<int:pk>/
์ ๋ํ CBVdef get(self, request):
pass
def post(self, request):
pass
def put(self, request):
pass
def delete(self, request):
pass
Tip! ๋ฉค๋ฒ ํจ์
ํด๋์ค์ ๋ด๋ถ์์ ์ ์๋ ํจ์๋ฅผ ๋ฉค๋ฒ ํจ์(member function)๋ผ๊ณ ํ๋ฉฐ, ๋๋ก๋ ๋ฉ์๋(method)๋ผ๊ณ ๋ถ๋ฆฌ๊ธฐ๋ ํจ
# views.py
class ArticleListCreateAPIView(APIView):
def get(self, request):
articles = Article.objects.filter(active=True)
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request):
serializer = ArticleSerializer(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)
class ArticleDetailAPIView(APIView):
def get_object(self, pk):
article = get_object_or_404(Article, pk=pk)
return article
def get(self, request, pk):
article = self.get_object(pk)
serializer = ArticleSerializer(article)
return Response(serializer.data)
def put(self, request, pk):
article = self.get_object(pk)
serializer = ArticleSerializer(article, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
article = self.get_object(pk)
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
def get_object(self, pk): article = get_object_or_404(Article, pk=pk) return article
# urls.py
urlpatterns = [
path("articles/",
ArticleListCreateAPIView.as_view(),
name="article-list"),
path("articles/<int:pk>/",
ArticleDetailAPIView.as_view(),
name="article-detail"),
]
.as_view()
๋ก ๋ผ์ฐํ
์ ํด์ฃผ๋ฉด View์์ ์ด๋ค์ ๋ถ๋ฌ์ ์์ฒญ์ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๊ฒ ๋จ# views.py
@api_view(["GET", "POST"])
def article_list_create_api_view(request):
if request.method == "GET":
articles = Article.objects.filter(active=True)
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
elif request.method == "POST":
serializer = ArticleSerializer(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)
@api_view(["GET", "PUT", "DELETE"])
def article_detail_api_view(request, pk):
try:
article = Article.objects.get(pk=pk)
except Article.DoesNotExist:
return Response({"error": {
"code": 404,
"message": "Article not found!"
}}, status=status.HTTP_404_NOT_FOUND)
if request.method == "GET":
serializer = ArticleSerializer(article)
return Response(serializer.data)
elif request.method == "PUT":
serializer = ArticleSerializer(article, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
try: article = Article.objects.get(pk=pk) except Article.DoesNotExist: return Response({"error": { "code": 404, "message": "Article not found!" }}, status=status.HTTP_404_NOT_FOUND)
# urls.py
urlpatterns = [
path("articles/",
article_list_create_api_view,
name="article-list"),
path("articles/<int:pk>/",
article_detail_api_view,
name="article-detail")
]
rest_framework.mixins
์์๋ ์ด๋ฌํ ๊ธฐ๋ฅ๋ค์ด ๋ฏธ๋ฆฌ ๊ตฌํ์ด ๋์ด ์์queryset
๊ณผ serializer_class
๋ฅผ ์ง์ ํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋จธ์ง๋ ์์ ๋ฐ์ Mixin๊ณผ ์ฐ๊ฒฐ๋จ# views.py
class EbookListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
queryset = Ebook.objects.all()
serializer_class = EbookSerializer
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
class EbookDetailMixins(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):
queryset = Ebook.objects.all()
serializer_class = EbookSerializer
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.delete(request, *args, **kwargs)
# urls.py
urlpatterns = [
path("ebooks/",
EbookListCreateAPIView.as_view(),
name="ebook-list"),
path("ebooks/<int:pk>/",
EbookDetailAPIView.as_view(),
name="ebook-detail"),
]
Tip! GenericAPIView
GenericAPIView์์๋lookup_field='pk'
๋ฅผ default๋ก ๊ฐ๊ณ ์์
Mixin
์ ์์ํจ์ผ๋ก์ ๋ฐ๋ณต๋๋ ๋ด์ฉ์ ๋ง์ด ์ค์ผ ์ ์์Mixin
์ ์์ํ ์๋ก์ด ํด๋์ค๊ฐ ์ ์๋์ด ์์# views.py
class EbookListCreateAPIView(generics.ListCreateAPIView):
queryset = Ebook.objects.all().order_by("id")
serializer_class = EbookSerializer
class EbookDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Ebook.objects.all()
serializer_class = EbookSerializer
# urls.py
urlpatterns = [
path("ebooks/",
EbookListCreateAPIView.as_view(),
name="ebook-list"),
path("ebooks/<int:pk>/",
EbookDetailAPIView.as_view(),
name="ebook-detail"),
]
generics.APIView
๋ฅผ ํตํด์ ์ฝ๋๋ฅผ ๋ง์ด ๊ฐ์ํ ํ์์ง๋ง ์์ง queryset
๊ณผ serializer_class
๊ฐ ๊ณตํต์ ์ธ๋ฐ๋ ๋ถ๊ตฌํ๊ณ ๋ฐ๋ก ๊ธฐ์ฌํด์ฃผ์ด์ผํ์ViewSet
ViewSet
์ CBV๊ฐ ์๋ ํฌํผ ํด๋์ค๋ก ๋ ๊ฐ์ง ์ข
๋ฅ๊ฐ ์์ViewSet
์ ๋ ์ข
๋ฅ ๋ชจ๋ ์์ฒด์ ์ธ ๊ตฌํ์ ์๊ณ Mixin
์ ์ ์ ํ ์์ ๋ฐ์ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ํ