당신은 멋쟁이, 우리는 장고쟁이~

0%

Django 간단한 투두리스트 API - 1

간단한 TodoList API 로 만들기


Django API RESTFRAMEWORK 학습을 진행 하면서 RESTFRAMEWORK 문서에 나와 있는 튜토리얼을 하나하나 따라서 진행 하며 학습을 해보았지만.

컨텐츠는 좋게 짜여진 튜토리얼이지만, 무언가 머리에 남는게 별로 없었다. 사실 처음 접했을때는 너무 어려웠었다. 따라서, 조금 쉬운 예제를 가지고 API 개발을 진행하면서 학습을 하기로 하였고. 여러모로 접근도 쉽고, 간편하게 짤수 있는 투두리스트 사이트를 API로 개발해 보면서, 학습을 진행해 보았다.


1. project 생성 및 앱 등록

가상환경과 Django 가 모두 세팅되었다고 가정하고.

projects/todo 폴더를 만들고 이동후에, 아래 커맨드들을 통해 Django 프로젝트를 생성해 주었다.


1
2
3
4
5
6
7
8
9
10
11
12
# todo 라는 django project 생성
django-admin startproject todo .

# 폴더 구조
~/projects/todo  ls
manage.py todo

# todolist 라는 앱 생성
python manage.py startapp todolist

~/projects/todo  ls
manage.py todo todolist # todolist 폴더가 생겨난다

제대로 프로젝트가 생성이 되었고, 앱도 생성이 되었다. 다른것을 하기전에, 생성된 앱을 todo/settings.pyINSTALLED_APPS 에 추가해주었다.


1
2
3
4
5
6
7
8
9
10
11

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

'todolist', # todolist 앱 추가
]


2. Migrations & Migrate


Django 프로젝트 생성후 앱 등록후에, 데이터베이스를 생성해 주었다.


1
2
3
4
5
6
7
8
python manage.py makemigrations 
python manage.py migrate
...................................
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying sessions.0001_initial... OK

서버를 구동해서 Django 사이트가 잘 작동하는지 확인해 보자.


1
python manage.py runserver

서버를 실행 시킨후에, 브라우저 주소창에 http://127.0.0.1:8000/를 입력 하면, 아래와 같은 화면이 표시되는걸 확인할수 있다.



3. 학습 목표


일반적인 사이트 개발이었을 경우, 다음 스텝들은 아래와 같이 그려볼수 있다.


  1. todolist 앱의 models.py 에 투두리스트에 대한 데이터 모델을 작성한다

  2. 프로젝트 urls.py 에 todolist/urls.py 를 연결해 주고, URL 구조를 만든다. 예를들면,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # todo/urls.py 

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

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

    # todolist/urls.py (urls.py 파일을 todolist 폴더안에 생성해줘야 함)


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

    urlpatterns = [
    # path('', )
    ]
  3. todolist/views.py 파일에 view 를 작성하고 todolist/urls.py 에 해당 view 를 등록하여, URL 요청이 있을때 어떻게 사이트가 작동할것인지에 대한 정의를 내림

  4. todolist 앱을 위한 템플릿 (즉, html 웹페이지들) 을 생성하고, 어떻게 view에서 처리된 데이터가 나타나게 될지 html, css, javascript 를 사용하여 html 페이지로 표현.


위 4가지를 대충만 작업하고 지나가도 시간이 너무 오래 걸리고 귀찮기 때문에 (특히, 프론트앤드). 웬만하면 API 학습 위주로만 연습을 해보기로 했다.

프론트 작업 없이, 작성된 API 만 확인하는 정도라면 위 4단계를 거치지 않고 학습을 진행 할수 있을것 같다.

TodoList 모델링


투두리스트 앱을 생성해 주었으니, 투두리스트 데이터 모델 부터 작성해 주기로 했다.


1.models.py


우선, todolist 폴더안에 models.py 파일을 열고 해당 파일에 데이터베이스 모델을 작성했다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.db import models
from django.contrib.auth.models import User
# Django 기본 User 모델을 가져옴

# Create your models here.

class TodoList(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField(blank=True)
dt_created = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.title


하나의 투두리스트를 생성하기 위한 데이터 정보들을 모델링 해주었다. 간단하게 각 필드에 대해 짚고 넘어가자면,


  1. user : 투두리스트를 작성한 사용자 정보
  2. title : 투두리스트의 타이틀 (제목)
  3. content : 투두리스트의 상세정보
  4. dt_created : 투두리스트 생성날짜와 시간

2. Migrations & Migrate


모델을 작성 하였으니, 데이터베이스에 모델을 적용해 보았다.


1
2
3
4
5
6
7
8
9
10
11
# python manage.py makemigrations 

Migrations for 'todolist':
todolist/migrations/0001_initial.py
- Create model TodoList

# python manage.py migrate

.................................
Running migrations:
Applying todolist.0001_initial... OK

3. Superuser 생성 하기


데이터를 생성하기 위해 관리자 계정 (Superuser) 하나를 생성해 주었다.

터미널에 아래 명령어를 실행해서, 관리자 계정을 생성하였다.


1
2
3
4
5
6
# python manage.py createsuperuser
Username (leave blank to use 'user'): todolist
Email address:
Password:
Password (again):
Superuser created successfully.

관리자 계정을 생성해 주었으니, Django 관리자 페이지로 들어가 보았다. python manage.py runserver 명령어를 실행시켜서 서버를 구동시키고, 브라우저에서 http://127.0.0.1:8000/admin 로 접속해 보면, 어드민 페이지로 들어갈수 있다.



생성된 superuser 아이디를 입력해서 어드민 페이지로 로그인 하면, 아래와 같이 어드민 페이지로 접속이 된다.



아직 기본 어드민에 어떠한 메뉴도 추가해주지 않았으므로, 현재 작성된 투두리스트 모델을 통해 데이터 생성은 어드민에서 할수가 없다.


4. 어드민에 TodoList 메뉴 추가해주기


todolist 앱에 models.py 파일에 투두리스트 모델을 작성해 주었다. 이제 해당 모델을 통해 어드민에서 데이터를 생성, 수정, 갱신, 삭제 동작을 할수 있도록 TodoList 모델을 어드민에 등록해 보도록 한다.


어드민에 작성된 모델을 등록하려면, todolist 폴더안에 admin.py 파일에 작성된 모델 정보를 등록해 주면 된다.


1
2
3
4
5
6
7
8
9
# todolist/admin.py 
from django.contrib import admin

# Register your models here.
# 모델에서 TodoList 모델을 가져옴
from .models import TodoList

# 어드민 사이트에 TodoList 모델을 등록
admin.site.register(TodoList)

admin.py 파일을 위와 같이 작성해 준다음, admin 에 다시 접속해 보면, 아래와 같이 TodoList 모델이 등록되어 있는것을 확인할수 있다.



TODOLIST 탭아래 Todolists 를 클릭해주면, ADD TODO LIST 버튼이 오른쪽 위에 존재하고.



ADD TODO LIST 버튼을 클릭하면, 어드민에서 Todolist 를 생성해 줄수 있다.



TodoList 데이터 생성


models.py 에 데이터베이스 모델을 정의해 주었는데. 정의된 대로, 데이터를 한번 생성해 보았다. 데이터를 생성하는 방법에는 두가지가 있는데. shell 과 admin을 이용해서 데이터를 추가해줄수 있다.


  1. shell 에서 데이터를 추가
  2. admin 에서 데이터를 추가

1. shell 로 데이터 추가해주기


shell 로 데이터를 추가해 주려면, 커맨드라인에서 django shell 로 들어가야 한다.


1
2
3
4
5
6
~/projects/todo  python manage.py shell
Python 3.8.0 (default, May 11 2020, 19:08:02)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.14.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]:

shell 의 모양이, 기본 모습과 다른데. 이건 django-extension 을 설치해줘서 모양이 바뀐것 같다.


투두리스트 하나를 생성할때 필요한 필드들은, 모델에 정의해 준대로. user, title, content, dt_created 가 있는데.


dt_created 는 생성된 날짜와 시간을 기록하는 필드로, auto_now=True 로 설정해 주었기에, 직접 입력을 하지않아도 자동으로 현재 날짜와 시간값으로 생성이 된다. 따라서, 하나의 투두리스트를 shell 로 생성해 주려면, 아래 명령어를 shell 에 입력하면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

In [1]: from todolist.models import TodoList

# 사용자 정보를 가져오기 위해, User 모델을 가져옴
In [2]: from django.contrib.auth.models import User

# 관리자는 첫번째 사용자임으로, id=1 로 생성된 사용자를 가져옴
In [3]: user = User.objects.get(id=1)

In [4]: user
Out[4]: <User: todolist>

# objects.create 메소드를 통해 데이터 생성, 사용자는 위에서 찾은 첫번째 사용자. 즉, 관리자.

In [5]: TodoList.objects.create(user=user, title="Djan
...: go API 학습하기", content="간단한 예제를 통해
...: API 학습 해보자.")
Out[5]: <TodoList: Django API 학습하기>

# 생성된 데이터 조회
In [6]: TodoList.objects.all()
Out[6]: <QuerySet [<TodoList: Django API 학습하기>]>

TodoList 데이터가 생성된것을 확인할수 있었다. Admin 에서도 생성해줄수 있는데. 어드민 페이지에 접속한후에,



화면에 나온 값들을 입력한뒤, Save 버튼을 눌러주면 생성된다.


2. Django-seed 를 이용해서 데이터 채워주기


예시 데이터를 채우기 위해서, shell 이나 admin 에 접속하여 일일이 하나씩 데이터를 생성해주는것은 너무 귀찮은 일이다. 만약 예시 데이터를 50개정도 추가해서 데이터를 보려 한다면, 50번을 위 과정을 거쳐야 함으로 매우 비효율적이다.


다행히도, Django 패키지 중에는 예시 데이터를 자동으로 생성해주는 패키지가 존재하는데. 책에서만 읽어 보았고, 직접 사용해 보지는 않았었기 때문에. 이번 연습때 한번 사용해 보도록 했다.


https://pypi.org/project/django-seed/#installation

pypi 페이지에 가면, django-seed 설치와 사용법에 대해 나와 있다.


우선, pip install django-seed 를 커맨드 라인에 입력하여, 패키지를 설치해주고. settings.py 파일에 INSTALLED_APPS 에 설치한 앱을 등록해 보았다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pip install django-seed 

# settings.py

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

'todolist',
# django-seed 등록
'django_seed',
]

공식문서를 보면, django-seed 의 사용법은 아래와 같다.


python manage.py seed <앱이름> --number=<생성 데이터 갯수>


이 사용법을 TodoList 앱에 적용해 사용해 보기 위해, 커맨드라인에 아래 명령어를 입력해 주었다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 10개의 데이터를 생성 
python manage.py seed todolist --number=10

Model User generated record with primary key 2
Model User generated record with primary key 3
Model User generated record with primary key 4
Model User generated record with primary key 5
Model User generated record with primary key 6
Model User generated record with primary key 7
Model User generated record with primary key 8
Model User generated record with primary key 9
Model User generated record with primary key 10
Model User generated record with primary key 11
Model TodoList generated record with primary key 2
Model TodoList generated record with primary key 3
Model TodoList generated record with primary key 4
Model TodoList generated record with primary key 5
Model TodoList generated record with primary key 6
Model TodoList generated record with primary key 7
Model TodoList generated record with primary key 8
Model TodoList generated record with primary key 9
Model TodoList generated record with primary key 10
Model TodoList generated record with primary key 11

커맨드라인에 몇가지 에러가 출력된것 같은데,, 결과적으론 10명의 User 와 10개의 투두리스트가 생성된것 같다. 생성된지 아닌지 확인해 보기 위해, 빠르게 shell 로 접속해서 데이터를 조회해 보았다.


1
2
3
4
5
6
7
8
9
10
python manage.py shell 

In [1]: from todolist.models import TodoList

In [2]: TodoList.objects.all()
Out[2]: <QuerySet [<TodoList: Django API 학습하기>, <TodoList: Law machine movement these effort that themselves.>, <TodoList: Start listen firm trouble defense husband collection.>, <TodoList: Really first product new no.>, <TodoList: Skin name certainly peace.>, <TodoList: Society as similar change team model agency.>, <TodoList: Prove dog page rest cover else.>, <TodoList: Deal test only exist without yourself.>, <TodoList: Letter operation run political require.>, <TodoList: Level truth green than defense industry Mrs.>, <TodoList: Help direction top task enough scientist.>]>

# TodoList 데이터의 갯수를 출력
In [3]: TodoList.objects.count()
Out[3]: 11

shell 에서 조회해 보니, TodoList 데이터 10개가 자동으로 생성된것을 확인할수 있었다.

이제 본격적으로 API를 만들어서 이렇게 생성된 데이터들을, API로 어떻게 생성, 조회, 갱신, 삭제 할수 있는지 알아볼수 있을것 같다.


Django REST framework


API를 개발하기 위해서는 필요한 Djang 패키지가 있다. Django REST framework 이라는것인데. 보통 Django 로 API 를 개발한다고 하면, 이 패키지를 설치하고 사용한다고 보면 된다.


1. Django REST framework 설치


설치를 진행 하려면, 커맨드 라인에 아래 명령어를 입력하여 패키지를 설치해주고.


1
pip install djangorestframework

설치 뒤에, settings.py 파일에 있는 INSTALLED_APPSrest_framework을 추가해 주면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14

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

'todolist',
'django_seed',
# django restframework
'rest_framework',
]


2. REST??


패키지를 설치하는김에 복습해 볼것은, REST 라는 단어인데. 이 REST 라는 컨셉은 API 개발을 이해하기전에 꼭 알아보고 진행 해야 하는 중요한 컨셉이다.


REST

Representational State Transfer (REST) 의 약자

https://www.techtarget.com/searchapparchitecture/definition/REST-REpresentational-State-Transfer

REST (REpresentational State Transfer) is an architectural style for developing web services. REST is popular due to its simiplicity and the fact that it builds upon existing systems and features of the internet’s HyperText Tyransfer Protocol (HTTP) in order to achieve its objectives.


영문으로 읽어봐도 뭔지 이해가 잘 가진 않는데..

2000년대에, Roy Fielding 이라는분이 처음 제안한 구조로, API를 웹상에서 개발하는 방범론이라고 이해하고 넘어가기로 했다. 즉, API 는 HTTP 프로토콜 위에 개발되는 방식을 REST 라고 보고 있다.



REST의 주요 특성


  1. HTTP 처럼 무상태 (Stateless) 이다

  2. 보편적인 HTTP verbs 를 지원한다 (예, GET, POST, PUT, DELETE)

  3. 데이터를 json 형태나 XML 형태로 반환한다.



이제, API 개발을 시작하기 위한 전반적인 준비는 다 마친것 같다. API 를 통해서 현재까지 생성된 데이터를 조회하는 API 부터 개발해 보도록 하려 한다.


API 작성


첫번째 API 개발을 시작하기전에, API 처리를 담당해줄 URL 구조를 세팅을 하였다.

현재, 프로젝트 앱 디렉토리 구조는 아래와 같은데.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.
├── db.sqlite3
├── manage.py
├── todo
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── todolist
├── admin.py
├── apps.py
├── __init__.py
├── migrations
│ ├── 0001_initial.py
├── models.py
├── tests.py
└── views.py

urls.py 파일


API 처리를 담당할 URL들을 설정해 주기 위해서, todolist 앱 안에, urls.py 파일을 생성해 주고. todo 폴더안에 있는 urls.py 파일과 연결해 주었다.


  1. 프로젝트 urls.py - todo/urls.py
  2. todolist 앱안에 urls.py 를 생성 - todolist/urls.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# todo/urls.py (기본 urls.py)

from django.contrib import admin
from django.urls import path, include # include 가져오기

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('todolist.urls'))
# todolist의 urls.py 를 포함시켜줌
]

# todolist/urls.py 생성후 아래와 같이 작성


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

urlpatterns = [
path('api/todolist',),
# api/ 다음에 오는 단어에 따라서 호출되는 API 뷰가 달라지게 url pattern을 작성할수 있다.
]

1. todolist 조회 API


현재까지 작성된 todolist 의 갯수는 11개 이다. 이 데이터들을 모두 조회할수 있는 가장 기본적인 API 작성을 해보았다.


django 로 무언가를 개발할때에는, 앱안에 urls.py, views.py 그리고 models.py 를 연관되게 작성해야 한다.


urls.py 에 정의된 url 을 통해서, views.py 파일에 정의된 view 를 호출하여 어떠한 작업을 수행하고, 호출된 뷰가 데이터를 가지고 작업을 해야하는 경우, models.py 에 정의된 데이터 모델을 참조해서 작업을 수행한다.

또한, 간단하게 API 개발을 할때에는 serializers.py파일까지 생성후 코드를 작성해 줘야 한다.


개발자마다, 어떤 파일부터 작업할지 순서가 다른데, 나는 serializers.py 파일부터 작업해 보기로 하였다.


조회 API 를 작성하기 위한 순서는,

  1. todolist 앱 안에 serializers.py파일 생성 및 작성 (todolist/serializers.py)
  2. views.py 파일에 TodoListAPIView 클래스 작성
  3. urls.py 파일에 url 정의 및 TodoListAPIView 를 호출하도록 코드 작성
  4. 테스트

1. serializers.py 파일 생성 및 작성


todolist/serializers.py 파일을 생성한뒤에 아래와 같이 작성해준다.


serializer 는 queryset 이나 모델 인스턴스 같은 복잡한 데이터들을 인터넷 상에서 쉽게 사용될수 있는 포맷으로 변환해 준다. 보통 json 형태로 전환한다.


1
2
3
4
5
6
7
8
9
# todolist/serializers.py 

from .models import TodoList
from rest_framework import serializers

class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = TodoList
fields = ("user", "title", "content", "dt_created")

2. views.py 에 TodoListAPIView 클래스 작성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# todolist/views.py 

from django.shortcuts import render

from .models import TodoList
from rest_framework import generics
# serializers.py 파일에서 정의한 TodoSerializer를 가져옴
from .serializers import TodoSerializer


# Create your views here.

class TodoListAPIView(generics.ListAPIView):
queryset = TodoList.objects.all()
serializer_class = TodoSerializer

rest_framework에서 generics 를 가져오면, generic 클래스로 쉽게 API 를 구현할수 있다. 일반 DJango 에서 generic 뷰인 ListView 같은 개념으로 보면 될것 같다.


3. urls.py 에 urlpattern 정의


이렇게 views 작성된 클래스를 어떤 urls 를 통해서 호출 될지 urlpattern 을 정의해 줘야 한다.


위에서 반쯤 정의되었던 todolist/urls.py 파일을 마저 작성하자.


1
2
3
4
5
6
7
8
9
# todolist/urls.py

from django.contrib import admin
from django.urls import path, include
from .views import TodoListAPIView # view 에서 작성한 TodoListAPIView 를 가져옴

urlpatterns = [
path('api/todolist/', TodoListAPIView.as_view(), name="todo-list"),
]

위에서 path 안에api/todolist/ 까지만 써줬는데, 해당 URL 을 통해 TodoListAPIView 클래스가 호출 되도록 urlpattern 하나를 정의 해주었다. 이제 api/todolist/ url 을 브라우저로 접속하면, API 를 통해 모든 TodoList 를 보여주는 기능이 추가 되었다.


4. 브라우저로 테스트 하기


python manage.py runserver 를 실행시켜 서버를 구동한다음. 브라우저의 주소창에


http://127.0.0.1:8000/api/todolist/ 를 입력하면 아래와 같은 화면을 확인 할수 있다.




브라우저에 해당 투두리스트의 디테일이 정상적으로 표시되는것을 확인할수 있었다.