안녕세계

[장고 AtoZ] Django REST Framewrok - ViewSet 본문

[장고 AtoZ] Django REST Framewrok - ViewSet

Junhong Kim 2018. 2. 6. 11:24
728x90
반응형

안녕하세요!

이번 포스팅부터는 DRF로 REST API를 만들어 보도록 하겠습니다.



※ 주의!!

본 포스팅은 setting.py 파일과 SECRET KEY를 분리한 상태에서 시작하기 때문에 초기 셋팅과 서버 실행법이 다릅니다.)

이전 포스팅을 따라서 동일한 환경을 구축한 뒤 따라하시면 됩니다!



[설치]

일단, django-rest-framework를 설치하지 않으신 분들은 설치해주세요 :D

 $ pip install djangorestframework

 


[앱 생성]

blog 앱을 생성해주세요

 $ django-admin startapp blog



[tutorial/base.py]

drf와 blog 앱을  INSTALLED_APPS에 등록합니다.

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



[blog/models.py]

Post model 클래스를 생성합니다.

from django.db import models


class Post(models.Model):
message = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)



[blog/serializers.py]

Post model의 serializer를 생성합니다.

- Class Meta의 model과 fields는 필수입니다.

- fields에는 serialize할 model 필드명을 명시합니다. (모든 필드는 __all__)

from rest_framework import serializers
from .models import Post


class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = '__all__'



[blog/views.py]

Post model의 viewSet을 생성합니다.

- 기본 CRUD를 한번에 만들기 위해 viewsets을 import합니다.

- viewsets.ModelViewSet을 상속하고 queryset과 serializer_class를 반드시 명시합니다.

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


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



[blog/urls.py]

viewset으로 만든 url을 맵핑합니다.

- DefaultRouter를  import하여 router를 등록합니다.

- router.register()에는 경로와 views.PostViewSet을 입력합니다.

- urlpatterns에 router.urls 를 include합니다. => 자동으로 URL이 생성됩니다.

from django.urls import include, path
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register('post', views.PostViewSet)

urlpatterns = [
path('', include(router.urls))
]



[tutorial/urls.py]

blog의 urls를 프로젝트 url에서 맵핑합니다.

(장고 2.x 부터는 1.x와 다른 방법으로 url을 맵핑하기 때문에 장고 1.x를 사용하고 계신분들은 이점을 유의하세요!)

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls'))
]


[서버 실행]

서버를 실행하기전에 우리가 마는 Post model을 makemigrations와 migrate를 해줘야합니다.

(우리는 이전 포스트에서 settings.py를 분리 했기 때문에 makemigrations와 migrate할 때도 settings 값을 명시해줘야 합니다.)


- makemigrations

 $ python manage.py makemigrations --settings=tutorial.settings.local


- migrate

 $ python manage.py runserver --settings=tutorial.settings.local



[모델 생성 결과]

위 명령어를 실행하면 아래 그림과 같이 성공적으로 model이 생성 된것을 확인할 수 있습니다.

(django-atoz) INMA@INMAui-MacBook-Pro tutorial (master)$ python manage.py makemigrations --settings=tutorial.settings.local

check:  (@qem)v@s#r-mkci48fm4hh&yo%n2g&0idhfvlnr+f0vmm7wew

Migrations for 'blog':

  blog/migrations/0001_initial.py

    - Create model Post

(django-atoz) INMA@INMAui-MacBook-Pro tutorial (master)$ python manage.py migrate --settings=tutorial.settings.local

check:  (@qem)v@s#r-mkci48fm4hh&yo%n2g&0idhfvlnr+f0vmm7wew

Operations to perform:

  Apply all migrations: admin, auth, blog, contenttypes, sessions

Running migrations:

  Applying contenttypes.0001_initial... OK

  Applying auth.0001_initial... OK

  Applying admin.0001_initial... OK

  Applying admin.0002_logentry_remove_auto_add... OK

  Applying contenttypes.0002_remove_content_type_name... OK

  Applying auth.0002_alter_permission_name_max_length... OK

  Applying auth.0003_alter_user_email_max_length... OK

  Applying auth.0004_alter_user_username_opts... OK

  Applying auth.0005_alter_user_last_login_null... OK

  Applying auth.0006_require_contenttypes_0002... OK

  Applying auth.0007_alter_validators_add_error_messages... OK

  Applying auth.0008_alter_user_username_max_length... OK

  Applying auth.0009_alter_user_last_name_max_length... OK

  Applying blog.0001_initial... OK

  Applying sessions.0001_initial... OK



[서버 실행]

이제, 서버를 실행하고 브라우저에서 접속해 봅시다.

 $ python manage.py runserver --settings=tutorial.settings.local


※ Tip!!

이제 빨간 글씨가 뜨지않죠? 빨간 글씨가 떳던 이유는 장고 프로젝트가 생성될 때 INSTALLED_APP 에 있는 내용들이 migrate 되지 않아서 떳던겁니다.

우리가 방금 Post model 과 같이 migrate 했기 때문에 이제 빨간 글씨가 뜨지 않아요!



[API TEST]

브라우저에 접속하면 localhost:8000/blog/ 에는 url 하나를 노출하고 있네요. 요거를 눌러봅시다


/blog/post 로 GET 요청을 보내니 비어있네요.

Message에 값을 입력하고 POST 요청을 보내보세요.


몇가지 데이터를 더 요청해서 보낸 뒤 다시 /blog/post/ 로 접속하면 우리가 만든 데이터가 보여집니다.

데이터를 생성한뒤 /blog/post/1/ 접속해보면 DELETE, PUT 작업까지 수행할 수 있습니다.


※ Tip

/blog/post/ API에서, post 부분이 추가되는 이유?


[blog.urls.py]

여기에 해답이있습니다.

- router에 등록할 때 post 를 입력해놨기 때문입니다. 'post' 대신 '' 을 입력해두면, /blog/ 로 접속했을 때 바로 포스트 리스트를 확인할 수 있습니다.

from django.urls import include, path
from rest_framework.routers import DefaultRouter
from . import views

router = DefaultRouter()
router.register('post', views.PostViewSet)

urlpatterns = [
path('', include(router.urls))
]


여기까지가 DRF viewSets를 활용한 기본 CRUD 만들기 였습니다!


저는 DRF를 이용해서 코드 몇줄로 CREATE, READ, UPDATE, DELETE 기능을 쉽게 API를 만들 수 있다는 점이 놀라웠습니다... ( ' 0')

다음 포스팅에서는 커스텀 (Params가 포함된 API, 기본 CRUD 커스텀 등) API를 만들어보도록 하겠습니다


감사합니다.


728x90
반응형
Comments