서버로부터 데이터를 받아올 때 한번에 다 받아올 수도 있지만 데이터가 많을 경우 일부분만 받아와야 할 경우가 생긴다. 예를 들면 대부분의 홈페이지에 게시판을 보더라도 한번에 모든 글들을 리스트로 보여주지 않고 아래 숫자로 page 를 넘기는 식으로 구현되어 있는데 이럴 경우에 사용하는 것이 Pagination 이다. Django RestFramework 에서는 기본적으로 Pagination 를 제공하는데 활용한다면 특별한 구현 필요 없이 자동으로 Page 로 구성이 된 형식으로 결과를 받아볼 수 있다. 아래는 공식 guide book 에서 설명한 pagination 이다. 아래의 링크를 보고 따라해도 되고 간단하니 내가 작성한 글을 따라 해도 된다.

https://www.django-rest-framework.org/api-guide/pagination/

 

Pagination - Django REST framework

pagination.py Django provides a few classes that help you manage paginated data – that is, data that’s split across several pages, with “Previous/Next” links. — Django documentation REST framework includes support for customizable pagination styles. This a

www.django-rest-framework.org

 

1. Setting.py 설정

 아래와 같이 REST_FRAMEWORK 의 Default Pagination Class 를 정의해주면 Pagination 된 결과를 확인할 수 있다.

LimitOffsetPagination 은 Parameter 를 통해 limit값과 offset 값을 줄 수 있는데, 예를 들어 get url 마지막에 limit=40&offset=100 이라고 보내준다면 40개의 데이터를 100번째 부터 달라는 의미이다.

 

Settings.py

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

무튼 Settings.py 만 정의해주면 아래같이 pagination 된 결과를 받을 수 있다. 아래에서 count field 는 총 Data 의 갯수이고 next 와 previous 는 다음 값과 이전 값의 url 이다. 현재는 default page_size 로 100이 선언이 되었기 때문에 다음 페이지가 필요가 없으므로 next가 null 로 비어 있다. 

2. Pagination Custom

Default 값으로 선언된 Pagination 말고도 직접 나의 Viewset 이나 GenericAPIView 에 내가 정의한 Pagination 을 할당 해 줄 수 있다. 공식 가이드 처럼 PageNumberPagination 를 override 해서 사용해보자. PageNumberPagination 은 파라미터로 Page 번호만 받는 방식이다. 

http://localhost:8000/posts/?page_size=2

views.py 에 PageNumberPagination 을 import 한 후 가이드처럼 LargeResultsSetPagination 이름의 PageNumberPagination 를 override 한 class 를 선언해준다 한번에 가져올 Data 갯수 parameter 로 사용할 page_size 를 정의 해주고 page_query_param 변수에 할당 해준다. max_page_size 는 최대 요청 가능한 page size 값이다.

 그리고 아래와 같이 Vieset 의 pagination_class 에 내가 정의한 LargeResultsSetPagination 를 할당해 준다.

 이러면 끝이다. 결과를 살펴보자. 참고로 GenericAPIView 에도 똑같은 방식으로 pagination_class 가 존재하고 값을 할당해 줄 수 있다.

 

views.py

...
from rest_framework.pagination import PageNumberPagination

class LargeResultsSetPagination(PageNumberPagination):
    page_size = 3
    page_query_param = 'page_size'
    max_page_size = 100

class PostViewset(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    pagination_class = LargeResultsSetPagination

page size 가 3으로 되어있고 Data 는 총 4개이기 때문에 next 에 다음 query 가 있는 것을 볼 수 있다.

 

3. 결과 확인

 next 를 눌러보면 다음 Data set 이 보여진다. 4개이니 next는 없고 이전값인 previous query 가 있는 것을 볼 수 있다.

 

기존에는 단순 results 의 List 만을 가지고 안드로이드의 retrofit 을 사용해서 restAPI 를 호출 하였지만 pagination 을 활용 하니 json 의 구조가 바뀌었다. 안드로이드에 바뀐 구조를 받아오는 restfit 예제도 실습한뒤에 포스팅 하겠다.

장고 server 를 테스트 하기 위해서 웹을 사용한다면 로컬에서도 충분히 확인을 할 수 있지만

IOS 나 Android 개발을 할 때 에 서버가 필요한 경우가 있다.

물론 돈을 내고 호스팅을 하거나 집에 서버 컴퓨터가 있으면 걱정이 없겠지만

단순히 테스트 용도로 사용하기에는 무리가 있다.

여러 방법을 찾던중 ngrok 을 사용하여 5분만에 내 컴퓨터를 테스트용 홈서버로 만드는 방법을 소개 하고자 한다.

 

1. ngrok download

https://ngrok.com/download 에 접속하여 ngork 을 다운로드 받는다.

 

2. django server 실행

 - 아래의 명령어로 장고 서버를 실행해 준다. 0.0.0.0:8000 의미는 현재 요청된 호스트의 IP나 이름에 상관없이 실행한다는 의미이다.

$ python manage.py runserver 0.0.0.0:8000

 - django project의 settings.py 수정

ALLOWED_HOSTS = ['*']

3. ngrok 실행

 - ngrok을 실행해보면 아래의 커맨드 화면이 보인다.

그리고 내가 연 포트번호를 넣어 아래의 명령어를 실행해준다.

>ngrok http 8000

 주소가 부여되는데 핸드폰 단말에서 해당 주소로 들어가면 내가 구성해놓은 rest api 페이지를 볼 수 있다.

 

ngrok 은 도메인을 할당하는 것 처럼 ngrok 을 통해서 고정 아이피와 나의 서버를 바인딩 해준다. 다른 서버를 들렸다 오는 것이므로 속도가 느리고 테스트용도로만 사용하자.

1. Restframework 설치

 - 터미널에 아래의 명령어를 입력시켜 준다.

pip install djangorestframework

 - settings.py 에 rest framework 추가 해준다.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]

2. 어플리케이션 생성

 - 어플리케이션을 생성한다.

$ python manage.py startapp myapp

 - setting.py 에 추가한다.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'myapp'
]

3. 모델 생성

 myapp/models.py 에 간단하게 아래의 post model class 를 추가해준다.

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    text = models.TextField()

아래의 명령어로 데이터 베이스에 모델을 위한 테이블을 형성한다.

$ python manage.py makemigrations myapp
$ python manage.py migrate

4. Serializers

쿼리셋, 모델 인스턴스 등의 복잡한 데이터를 json, xml 등의 데이터로 변환해준다.

-  myapp/serializers.py 생성 후 아래의 코드를 입력한다.

from rest_framework import  serializers
from .models import Post

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ('title', 'text')

 

5. Views

 Viewset 하나에 다양한 method를 포함하고 있다.

 - myapp/views.py 수정한다.

from rest_framework import viewsets
from .serializers import PostSerializer
from .models import Post

class PostViewset(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

 

6. urls 

router 를 설정해 준다. router 는 URL을 자동으로 맵핑해준다.

 - project/urls

from rest_framework import routers
from myapp import views
from django.conf.urls import url, include

router = routers.DefaultRouter()
router.register(r'posts', views.PostViewset)


urlpatterns = [
    url(r'^',include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

 

7. 서버 실행 후 동작 확인

$ python manage.py runserver

 - http://127.0.0.1:8000/

서버를 실행 후 위 주소로 들어가면 Default router에 의해서 접근할 수 있는 URL 인 http://127.0.0.1:8000/posts가 표시된다.

http://127.0.0.1:8000/posts에 접속을 해보면 아래와 같이 post list를 볼 수 있다. 현재는 데이터를 하나도 등록을 안시켰으므로 비어 있다.

하단의 title 과 text 에 test 문구를 넣어주고 post 버튼을 눌러보자. post 를 누르면 post된 data만 보이게되고

다시 오른쪽 상단의 get버튼으로 list를 다시 받아오면 아래와 같이 내가 등록했던 data list를 볼 수 있다.

 

기본적으로 rest framework 을 구성해 보았다. 

다음 시간에는 안드로이드와 연결되서 실제로 어떻게 쓸 수 있는지 알아보고자 한다.

+ Recent posts