๐Ÿ“ƒDjango DRF ViewSet์„ ํ™œ์šฉํ•œ Pagination

๊น€ํƒœ์ธยท2022๋…„ 9์›” 8์ผ
0
post-thumbnail

๐Ÿ“Œ๊ธฐํš

  • DRF์˜ ํŽ˜์ด์ง€๋„ค์ด์…˜ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ, ์‰ฝ๊ณ  ๋น ๋ฅด๊ฒŒ API๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค
  • ๊ณต์‹๋ฌธ์„œ์˜ Viewset์„ ํ•™์Šตํ•˜์—ฌ, ๊ธฐ์กด์˜ View, generic View์™€์˜ ์ฐจ์ด์ ์„ ์•Œ์•„๋ณด์ž

๐Ÿ“Œํ•™์Šต๋ชฉ์ 

  • DRF ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ View๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค
  • ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ Request์™€ Response๋ฅผ ๋™์ผํ•˜๊ฒŒ ๊ตฌํ˜„ํ•œ๋‹ค
  • ๊ณต์‹๋ฌธ์„œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Viewset์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค

๐Ÿ“Œ์ฐธ์กฐ

๐Ÿ‘โ€๐Ÿ—จDRF VIEWSET

6 - Viewsets and routers - Django REST framework

๐Ÿ‘โ€๐Ÿ—จDRF ํŽ˜์ด์ง€๋„ค์ด์…˜

Pagination

๐Ÿ“ŒViewSet๊ตฌํ˜„

#setting.py

REST_FRAMEWORK = {
	'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
	'PAGE_SIZE': 15,
}
#Archive view ์ž‘์„ฑ
from rest_framework import viewsets

class ArchaivePaginationViewSet(viewsets.ModelViewSet):
    queryset = ArchiveModel.objects.all()
    serializer_class = ArchiveSerializer
    pagination_class = PageNumberPagination
#urls.py

from .views import ArchaivePaginationViewSet
pagination = ArchaivePaginationViewSet.as_view({
    'get': 'list',
    'post': 'create'
})

urlpatterns = [
	path('pagination/', pagination, name='archive_pagination'),
]

๐Ÿ“ŒGeneric๊ตฌํ˜„

#setting.py

REST_FRAMEWORK = {
	'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
	'PAGE_SIZE': 15,
}
#urls.py

urlpatterns = [
	path('pagination/', views.ArchaivePagination.as_view(), name='archive_pagination'),
]
# Archive view ์ž‘์„ฑ

class ArchaivePagination(generics.ListAPIView):
    queryset = ArchiveModel.objects.all()
    serializer_class = ArchiveSerializer
    pagination_class = PageNumberPagination

๐Ÿ“Œํ•™์Šตํฌ์ธํŠธ

๐Ÿ–‹APIView์™€, Generic View, Viewset์€ ์–ด๋–ค ์ฐจ์ด์ ์ด ์žˆ๋Š”๊ฐ€?

  • DRF์—์„œ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” View ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ APIView, Generic View, Viewset ์„ธ ๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„๋œ๋‹ค.
  • APIView๋Š” RestAPI ๋ฐฉ์‹์œผ๋กœ HTTP Method๋ฅผ ํ•จ์ˆ˜๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” CBV ํ˜•์‹์˜ View ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด๋‹ค. URL์— View๋งŒ as_view() ํ˜•์‹์œผ๋กœ ์—ฐ๊ฒฐํ•ด๋‘๋ฉด HTTP Request Method์— ๋”ฐ๋ผ์„œ ํ•ด๋‹น Method์˜ ์ด๋ฆ„์— ๋งž๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค
  • Generic View๋Š” ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” View๋ฅผ ์ƒ์†๋ฐ›์•„ ๊ธฐ๋Šฅ์„ ๊ทธ๋Œ€๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ๊ฒ€์ƒ‰, ํ•„ํ„ฐ ๋“ฑ ํŠน์ • API๋ฅผ ์ƒ์†๋ฐ›์•„ ์ •ํ•ด์ง„ ํ˜•์‹์˜ ํ•„๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋น ๋ฅด๊ฒŒ View๋ฅผ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • Viewset์€ APIView์™€ Generic View๋ฅผ ํ•ฉ์นœ ํ˜•ํƒœ์ด๋ฉฐ, ๋ฆฌ์ŠคํŠธ ๋ณด๊ธฐ๋ฅผ ํฌํ•จํ•œ REST API๋ฅผ ๋ชจ๋‘ ๋…ํŠนํ•˜๊ฒŒ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฉ”์„œ๋“œ์™€ ์—ฐ๊ฒฐํ•˜์—ฌ ๋ชจ๋‘ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•œ CBV์ด๋ฉฐ, ๋˜ํ•œ ๋ฏธ๋ฆฌ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” API๋ฅผ ์ƒ์†ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋น ๋ฅด๊ฒŒ View๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. Viewset์€ URL์—์„œ ๋ณ€์ˆ˜๋กœ ๋ทฐ๋ฅผ as_view() ์•ˆ์—์„œ list, retrieve, create, update, destroy ๋“ฑ์˜ ๋ฉ”์„œ๋“œ์™€ ๋งคํ•‘ํ•˜์—ฌ ์„ ์–ธํ•œ ๋’ค, UrlPatterns ์•ˆ์—์„œ ๋ณ€์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๐Ÿ–‹Pagination์˜ ๊ตฌํ˜„์ˆœ์„œ๋ฅผ ๋ฆฌ๋งˆ์ธ๋“œ

  • setting.py ์— REST_FRAMEWORK ์•ˆ์— ๊ณต์‹๋ฌธ์„œ example์„ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๊ธฐ์žฌ
  • ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ์ ์šฉํ•  ์•ฑ์— views.py ๋กœ ์ด๋™ํ•˜์—ฌ ViewSet์„ ์ƒ์†๋ฐ›์€ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ ํ›„, ๋ชจ๋ธ๊ณผ ์‹œ๋ฆฌ์–ผ๋ผ์ด์ €, ํŽ˜์ด์ง€ ๋„˜๋ฒ„๋ฅผ ๊ธฐ์žฌํ•œ๋‹ค
  • urls.py ์— pagination์œผ๋กœ ์ด๋™ํ•  ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•ด์คŒ์œผ๋กœ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค

๐Ÿ–‹๊ณต์‹๋ฌธ์„œ ์–ด๋–ป๊ฒŒ ์ฝ์—ˆ๋‚˜?

  • PageNumberPagination์„ ์ฐธ์กฐํ–ˆ์Œ!

ํŽ˜์ด์ง€๋„ค์ด์…˜ API Request&Response

๐Ÿ’ก์•„! ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ์ด๋ ‡๊ฒŒ ์š”์ฒญํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š”๊ตฌ๋‚˜!

# Request
GET https://api.example.org/accounts/?page=4

# Response
HTTP 200 OK
{
    "count": 1023,
    "next": "https://api.example.org/accounts/?page=5",
    "previous": "https://api.example.org/accounts/?page=3",
    "results": [
       โ€ฆ
    ]
}

ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์…‹์—…

๐Ÿ’กsettings.py ์—์„œ REST_FRAMEWORK๋ผ๋Š” ๋ณ€์ˆ˜ ์•ˆ์— ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ๋”ฐ๋กœ ๋„ฃ์–ด์ฃผ๋Š”๊ตฌ๋‚˜!

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100
}

๊ธฐ๋ณธ์ ์ธ ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฝ”๋“œ ์Šคํƒ€์ผ

๐Ÿ’ก์•„ ํŽ˜์ด์ง€๋„ค์ด์…˜์€ ์ด๊ฑธ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์“ฐ๋ฉด ๋˜๊ฒ ๊ตฌ๋‚˜!

  • ์ฟผ๋ฆฌ์…‹์€ ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ ํ˜•์‹์ด๊ตฌ๋‚˜! ๋‚˜๋Š” ์•„์นด์ด๋ธŒ๋ชจ๋ธ์„ ๊ฐ€์ ธ์™€์„œ ์“ฐ๋ฉด ๋˜๊ฒ ๋‹ค!
  • ์‹œ๋ฆฌ์–ผ๋ผ์ด์ € ํด๋ž˜์Šค๋Š” ์‹œ๋ฆฌ์–ผ๋ผ์ด์ € ๊ฐ€์ ธ๋‹ค ๋ถ™์ด๋ฉด ๋˜๊ตฌ๋‚˜!
  • ํŽ˜์ด์ง€๋„ค์ด์…˜ ํด๋ž˜์Šค๋Š” ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ํŽ˜์ด์ง€๋„ค์ด์…˜์„ ๊ฐ€์ ธ๋‹ค ๋ถ™์ด๋ฉด ๋˜๊ตฌ๋‚˜! ๊ณต์‹๋ฌธ์„œ ๋ณด๊ณ  ํ›”์ณ์•ผ์ง€
class BillingRecordsView(generics.ListAPIView):
    queryset = Billing.objects.all()
    serializer_class = BillingRecordsSerializer
    pagination_class = LargeResultsSetPagination

ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž„ํฌํŠธ

# views.py์˜ ํŽ˜์ด์ง€๋„ค์ด์…˜ ํด๋ž˜์Šค์— ๋ถ™์ผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
from rest_framework.pagination import PageNumberPagination

# views.py์˜ ์ œ๋„ˆ๋ฆญ ๋ทฐ๋ฅผ ์ƒ์†๋ฐ›๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
from rest_framework import generics
profile
์ฝ”๋”ฉ์ด ์ทจ๋ฏธ๊ฐ€ ๋˜๋Š” ๊ทธ๋‚ ๊นŒ์ง€

0๊ฐœ์˜ ๋Œ“๊ธ€