Computer Science/BackEnd

Django for APIs | #4 Todo API

토마토. 2022. 9. 27. 11:34
Chapter 3
Todo API
Initial Set up

python 가상환경 설정

pip django, djangorestframework 설치

 

(backend) $ django-admin startproject todo_project .
(backend) $ python manage.py startapp todos
(backend) $ python manage.py migrate

 

INSTALLED_APPS = [
    'todos.apps.TodosConfig',  # new, local app
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 

models

 

from django.db import models

# Create your models here.


class Todo(models.Model):
    title = models.CharField(max_length=200)
    body = models.TextField()

    def __str__(self):
        return self.title

 

 

(backend) $ python manage.py makemigrations todos
(backend) $ python manage.py migrate

 

from django.contrib import admin

# Register your models here.
from .models import Todo

admin.site.register(Todo)

 

(backend) $ python manage.py createsuperuser
(backend) $ python manage.py runserver

 

Django REST Framework
INSTALLED_APPS = [
    'rest_framework',
    'todos.apps.TodosConfig',  # new, local app
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 

 

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.AllowAny',
    ]
}

 

우선, 사용 권한을 모든 것을 허용하도록 명시적으로 설정한다. AllowAny

 

 

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

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

 

 

from django.urls import path
from .views import ListTodo, DetailTodo

urlpatterns = [
    path('<int:pk>/', DetailTodo.as_view()),
    path('', ListTodo.as_view()),
]

 

Serialziers
from rest_framework import serializers
from .models import Todo


class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = ('id', 'title', 'body',)

 

Views
from rest_framework import generics
from .models import Todo
from .serializers import TodoSerializer

# Create your views here.


class ListTodo(generics.ListAPIView):
    queryset = Todo.objects.all()
    serialzier_class = TodoSerializer


class DetailTodo(generics.RetrieveAPIView):
    queryset = Todo.objects.all()
    serialzier_class = TodoSerializer

 

Consuming the API

예전에는 API를 시각화가 어려웠지만, 

오늘날에는 postmen 등을 통해 쉽게 API를 시각화할 수 있다. 

심지어 Django REST Framework에서는 브라우징API를 제공하여 브라우저를 통해 API를 확인할 수 있다. 

 

 

CORS

CORS Cross-Origin Resource Sharing

Cross-Origin Resource Sharing (CORS) - HTTP | MDN (mozilla.org)

CORS는 왜 이렇게 우리를 힘들게 하는걸까? | Evans Library (evan-moon.github.io)

 

클라이언트ㅡ가 다른 도메인, 포트에서 호스팅되는 API와 상호작용할 때마다 잠재적인 보안 이슈가 발생한다. 그래서 CORS Cross-Orgin Resource Sharing은 클라이언트가 다른 출처의 도메인 요청을 허용할지 여부와 허용할 시기를 결정할 수 있도록 서버가 특정한 HTTP 헤더를 포함하도록 요구한다. 

Django API 백엔드의 경우, 로컬 개발에서는 다른 포트에 위치한 전용 프론트엔드와 통신하고, 배포하고 나면 다른 도메인에 있다. Django rEST Framework에서는 HTTP 헤더를 자동으로 만들어주는 미들웨어를 사용하는 것이다. 

django-cors-headers 패키지를 이용하면 쉽게 기존 프로젝트에 CORS를 추가할 수 있다. 

 

$ pip install django-cors-headers

 

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

 

 

CORS_ORIGIN_WHITELIST = (
    'http://localhost:3000',
    'http://localhost:8000',
)

 

3000 포트는 프론트엔드에서 사용할 것이다. 

 

Tests
from django.test import TestCase
from .models import Todo

# Create your tests here.


class TodoModelTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        Todo.objects.create(title='first todo', body='a body here')

    def test_title_content(self):
        todo = Todo.objects.get(id=1)
        expected_object_name = f'{todo.title}'
        self.assertEquals(expected_object_name, 'first todo')

    def test_body_content(self):
        todo = Todo.objects.get(id=1)
        expected_object_name = f'{todo.body}'
        self.assertEquals(expected_object_name, 'a body here')

 

 

$ python manage.py test
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..
----------------------------------------------------------------------
Ran 2 tests in 0.003s

OK
Destroying test database for alias 'default'...

 

반드시 테스트 생활화할 것!

 

 

Conclusion

Django REST Framework는 최소한의 코드로 Django API를 만들 수 있다. 

 

'Computer Science > BackEnd' 카테고리의 다른 글

Django for APIs | #6 Permissions  (0) 2022.10.01
Django for APIs | #5 blog API  (0) 2022.09.30
Django for APIs | #3 Library Website and API  (0) 2022.09.27
Django for APIs | #2 Web APIs  (1) 2022.09.26
Django for APIs | #0 Introduction  (0) 2022.09.18