프로그래밍/Python

django 에서 REST API 만들기

Terry Cho 2014. 1. 8. 00:58

Dango에서 간단한 REST API 만들기 

조대협



Django에서 REST API를 만들려면 가장 널리 사용되는 프레임웍중 하나가 dango rest_framework이다.

http://django-rest-framework.org/tutorial/quickstart


설치는 다음과 같다.

pip install djangorestframework

pip install markdown       # Markdown support for the browsable API.

pip install django-filter  # Filtering support

 

1. quickstart라는 앱을 생성

 

C:\Users\terry\git\django_restframework_sample\django_restframework_sample>python manage.py startapp quickstart

또는 이클립스 사용시에는 project에서 오른쪽 버튼 누르고 django 메뉴에서 > Custom command (manage.py xxx)에서 startapp 명령어 실행

 



아래와 같이 프로젝트 아래에 앱이 생성된



 

2. DB sync

setting.py에 아래 내용을 추가

DATABASES = {

    'default': {

        'ENGINE': 'django.db.backends.sqlite3',

        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

        'USER': '',

        'PASSWORD': '',

        'HOST': '',

        'PORT': ''

    }

}

다음 eclipse에서 마찬가지로 오른쪽 버튼을 눌러서, django 메뉴에서 manage.py syncdb 명령어를 수행



이 예제에서는 실제 테이블은 만들지 않고, API 인증을 위해서, django user 테이블만을 생성한다. Syncdb를 수행하면 아래와 같이 첫 user를 만드는데, 이때, 사용자 id,email,password를 입력하도록 한다.



 

3. 다음으로 코딩

1) quickstart/serializer.py 코드를 아래와 같이 작성

from django.contrib.auth.models import User, Group

from rest_framework import serializers

 

 

class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:

        model = User

        fields = ('url', 'username', 'email', 'groups')

 

 

class GroupSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:

        model = Group

        fields = ('url', 'name')

 

2) quickstart/views.py를 다음과 같이 작성

from django.contrib.auth.models import User, Group

from rest_framework import viewsets

from quickstart.serializers import UserSerializer, GroupSerializer

 

 

class UserViewSet(viewsets.ModelViewSet):

    """

    API endpoint that allows users to be viewed or edited.

    """

    queryset = User.objects.all()

    serializer_class = UserSerializer

 

 

class GroupViewSet(viewsets.ModelViewSet):

    """

    API endpoint that allows groups to be viewed or edited.

    """

    queryset = Group.objects.all()

    serializer_class = GroupSerializer

 

위의 테스트 앱은 UserViewSet은 현재 Django에 등록된 사용자 리스트들을 읽어다가 JSON으로 리턴하는 클래스 이고, GroupViewSet은 마찬가지로 django에 등록된 사용자 그룹 리스트를 읽어다가 JSON으로 리턴하는 클래스이다.

 

Rather than write multiple views we're grouping together all the common behavior into classes called ViewSets.

We can easily break these down into individual views if we need to, but using viewsets keeps the view logic nicely organized as well as being very concise.

Notice that our viewset classes here are a little different from those in the frontpage example, as they include queryset andserializer_class attributes, instead of a model attribute.

For trivial cases you can simply set a model attribute on the ViewSet class and the serializer and queryset will be automatically generated for you. Setting the queryset and/or serializer_class attributes gives you more explicit control of the API behaviour, and is the recommended style for most applications.

4. 다음으로 세팅

1) root project(여기서는 django_restframework_sample) urls.py에 다음 코드를 추가함

from django.conf.urls import patterns, url, include

from rest_framework import routers

from quickstart import views

 

router = routers.DefaultRouter()

router.register(r'users', views.UserViewSet)

router.register(r'groups', views.GroupViewSet)

 

# Wire up our API using automatic URL routing.

# Additionally, we include login URLs for the browseable API.

urlpatterns = patterns('',

    url(r'^', include(router.urls)),

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

)

일반적인 web application과 다르게 view가 아닌 viewset을 사용하기 때문에, URL rest_framework이 자동으로 설정하도록 세팅하였다.

l  /users à views.UserViewSet API로 맵핑 되고

l  /groups à views.GroupViewSet API로 맵핑 된다.

 

2) Root project setting.py에 다음을 추가

REST_FRAMEWORK = {

    'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAdminUser',),

    'PAGINATE_BY': 10

}

이 부분이 흥미로운 부분인데, JSON 기반의 API 인증(Authentication)  인가(Authorization)을 프레임웍 자체에서 제공한다. 위의 경우에는 Admin 사용자에 대해서만 서비스를 제공하고, HTTP BASIC AUTH 인증을 사용한다.

http://django-rest-framework.org/api-guide/permissions 에 자세한 내용이 나와 았는데,  

  모든 사용자에게 access를 허가하는 Allow Any

  인증된 사용자에게만 access를 허가하는 isAuthenticated

  관리자에게만 인증을 허가하는 isAdminUser

  인증되지 않은 사용자에게는 Read,인증된 사용자에게는 Update를 제공하는 isAuthenticatedOrReadOnly

  기타 DjangoModel (django.contrib.auth에 의해서 관리되는 권한)이나 Object 단위 권한등에 따라서, 조정할 수 있다.

  그리고 TokenHasReadWriteScope의 경우에는 OAuth2Authentication등과 연계하여 Token 기반의 인증이 가능하게 된다.

※ 다양한 인증 메커니즘을 제공하기 때문에, 처음에는 어려울지 몰라도, 이해하고 나면 짜는 것 보다는 훨씬 쉬울듯.

위는 API접근 권한에 대한 것이었고, Authenticationhttp://django-rest-framework.org/api-guide/authentication 에 정의되어 있다. 위에서 사용한 것과 같이 HTTP Basic Auth를 사용할 수 도 있고, Token이나 Http Session 기반의 Authentication 그리고, OAuth 1,2 기반의 인증을 모두 지원한다. (Token 방식의 경우에는 userauthenticated된 다음, Authorization token을 서버에서 발급해준다. Token HTTP를 타고 내려가기 때문에, Token secure하게 전달하기 위해서 HTTPS를 필수로 사용해야 한다.)

 

 

3) 그리고, setting.py INSTALLED_APPS rest_framwwork을 추가하는 것도 있지 말자

INSTALLED_APPS = (

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'rest_framework',

)

5. 테스팅

테스트는 Chrome plug-inadvanced rest client를 사용하였다.

여기서 주목할 것은 HTTP Basic Auth 헤더를 어떻게 입력하느냐인데,

Headers 메뉴에서 Form을 선택한후 Add new header에서 Key Authorization을 선택한다.



Authorization이 선택되면 value를 넣는 부분에 아래와 같이 Construct라는 버튼이 나타나는데,



이 버튼을 누르게 되면 아래와 같이 dialog box가 나와서 basic 며소에 대한 log in id password를 넣을 수 있게 된다.



이 과정이 끝나면 Header 부분에 HTTP Basic Auth 부분이 들어가게 되고, 아래와 같은 테스트 결과를 얻게 된다.

 




대부분의 내용은 http://django-rest-framework.org/tutorial/quickstart 를 참고하였음