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']>,
]