ViewSet & Router
๐ก ViewSet
2๊ฐ์ URL์ ์ง์ํ๋ค. ํ๋์ URL์ list/create๋ฅผ ์ง์ํ๊ณ ,
๋๋จธ์ง ํ๋๋ detail/update/partial_update/delete๋ฅผ ์ง์ํ๋ค.
์์ ๊ฐ์ด 2๊ฐ๋ก ๋๋์๋ ์์ง๋ง, ViewSet
์์๋ 2๊ฐ์ URL ๊ตฌํ์
ํ๋์ ๋จ์ผ ํด๋์ค์์ ์ ๊ณตํด์ค๋ค.
ViewSet ์ ์ธ ๊ฒฝ์ฐ
from rest_framework import generics
class PostListAPIView(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
class PostDetailView(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
ViewSet ์ธ ๊ฒฝ์ฐ
# urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('post', view.PostViewSet)
urlpatterns =[
path('',include(router.urls)),
]
# views.py
from rest_framework.viewsets import ModelViewSet
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
๐ก ModelViewSet
ModelViewSet์๋ ๋ ๊ฐ์ง๊ฐ ์๋ค.
๏ผ. viewsets.ReadOnlyModelViewSet
GET ์์ฒญ์๋ง ๋ฐ์ํ๋ ViewSet
list ์ง์
detail ์ง์
๏ผ. viewsets.ModelViewSet
list/create ์ง์ (1๊ฐ์ URL)
detail/update/partial_update/delete ์ง์ (1๊ฐ์ URL)
๐ก Router
๋ฆฌ์์ค ๋ผ์ฐํ ์ ์ฌ์ฉํ๋ฉด ๋ณ๋์ ๊ฒฝ๋ก๋ฅผ ์ ์ธํ๋ ๋์
์ฃผ์ด์ง ๋ฆฌ์์ค์ ๋ํ ๋ชจ๋ ๊ณตํต ๊ฒฝ๋ก๋ฅผ ๋น ๋ฅด๊ฒ ์ ์ธํ ์ ์๋ค.
router.urls๋ฅผ ์ถ๋ ฅํด ๋ดค๋๋ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ์๋์ ๊ฐ์๋ค.
[
<URLPattern '^post/$' [name='post-list']>,
<URLPattern '^post\.(?P<format>[a-z0-9]+)/?$' [name='post-list']>,
<URLPattern '^post/(?P<pk>[^/.]+)/$' [name='post-detail']>,
<URLPattern '^post/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='post-detail']>,
<URLPattern '^$' [name='api-root']>,
<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>
]
post-list์ detail-list๊ฐ ์์ฑ๋ ๊ฑธ ํ์ธํ ์ ์์๋ค.
๊ทธ๋ฆฌ๊ณ format์ ์ง์ํด์ฃผ๋ URL๋ ๊ฐ์ด ์์ฑ๋๋ค. ๋ฐ๋ผ์ URL์ฐฝ์
/post/1.json
๊ณผ ๊ฐ์ด ์
๋ ฅ์ ํ๊ฒ ๋๋ฉด, ์๋์ ๊ฐ์ด jsonํ์์ผ๋ก ๋์จ๋ค.
๋ง์ง๋ง์ ์์ฑ๋ api-root๋ ํ์ฌ router์ ๋ฑ๋ก๋ ๋ฆฌ์์ค์ ๋ํ ๋ชฉ๋ก์ ๋ณผ ์ ์๋ค.
๐ก ViewSet์ ์๋ก์ด EndPoint ์ถ๊ฐํ๊ธฐ
@action
ViewSet์ @action์ ํตํด ๋ฉ์๋๋ฅผ ๋ฐ์ฝ๋ ์ด์ ํ์ฌ
์๋ก์ด EndPoint๋ฅผ ํ์ํ ์ ์๋ค.
# views.py
class PostView(ModelViewSet):
queryset = Post.object.all()
serializer_class = PostSerializer
@action(detail=False, methods=['GET'])
def public(self,request):
qs = self.get_queryset().filter(is_public=True)
serializer = self.get_serializer(qs, many=True)
return Response(serializer.data)
@action(detail=True, method=['PATCH'])
def set_public(self,request,pk):
instance = self.get_object()
instance.is_public = True
instance.save(update_fields=['is_public'])
serializer = self.get_serializer(instance)
return Response(serializer.data)
get_object(), get_serializer(), get_queryset() ์ด ์ธ ํจ์๋
์๋ ๋งํฌ์์ ์์ค ์ฝ๋๋ฅผ ํตํด ์ดํดํ๊ธฐ.
๐ GenericAPIView ๊นํ๋ธ ์์ค์ฝ๋
์ด๋ฌํ ์ถ๊ฐ ์์ ์ ํตํด ์์ฑ๋ URL์ ์๋์ ๊ฐ์ด ๊ธฐ์กด URLPattern์ ์ถ๊ฐ๋๋ค.
(๋ฐ์ 4์ค์ด ์๋ก ์ถ๊ฐ๋ URLPattern์ด๋ค.)
[
#====================================== ๊ธฐ์กด URLPattern ======================================#
<URLPattern '^post/$' [name='post-list']>,
<URLPattern '^post\.(?P<format>[a-z0-9]+)/?$' [name='post-list']>,
<URLPattern '^post/(?P<pk>[^/.]+)/$' [name='post-detail']>,
<URLPattern '^post/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='post-detail']>,
<URLPattern '^$' [name='api-root']>,
<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>]
#===================================== ์ถ๊ฐ ๋ URLPattern =====================================#
<URLPattern '^post/(?P<pk>[^/.]+)/set_public/$' [name='post-set-public']>,
<URLPattern '^post/(?P<pk>[^/.]+)/set_public\.(?P<format>[a-z0-9]+)/?$' [name='post-set-public']>,
<URLPattern '^post/public/$' [name='post-public']>,
<URLPattern '^post/public\.(?P<format>[a-z0-9]+)/?$' [name='post-public']>,
]