Python

Python - Django REST Framework 초기 설정

Todo 앱을 Python DRF를 사용하여 만들고 설정에 대해 정리한다. Backend는 Django로 Frontend는 Vue로 구현해보려한다.

Django를 사용하기 위해 필요한 Python 패키지는 아래와 같다.


패키지 설치

# django
# djangorestframework
# django-cors-headers # Cross Domain 에러를 처리하기 위한 패키지이다. 
# drf-yasg  # swagger API 명세를 작성할 수 있다.
# django-extensions  # shell_plus와 같은 편리한 기능을 제공해준다.

$ pip install django djangorestframework django-cors-headers drf-yasg django-extensions

프로젝트 생성

터미널에서 myProject라는 폴더 생성후 backend와 frontend로 폴더를 추가 생성후 backend 폴더로 이동후 Django startproject 명령어를 입력하여 프로젝트를 생성하였다. 프로젝트 이름은 config로 하였다. 

$ django-admin startproject config .

명령어 실행 후 Django 초기 파일이 아래와 같이 생성된다.


Django todo 앱 생성

backend 폴더 위치에서 Django todo 앱을 생성 한다.

$ python manage.py startapp todo  

 

models.py, views.py 파일은 삭제 후 models, views 폴더를 생성한다. models, views 폴더 각각에 todo.py, __init__.py을 생성한다.

backend/models/todo.py 파일내용은 아래와 같이 작성한다.

from django.db import models

# Create your models here.
class Todo(models.Model):  # 필드와 그 옵션을 정의합니다.
    title = models.CharField(
        max_length=64,
        verbose_name="제목",
        help_text="제목"
    )
    description = models.CharField(
        max_length=256,
        null=True,
        blank=True,
        verbose_name="설명",
        help_text="설명"
    )
    author = models.CharField(
        max_length=16,
        verbose_name="작성자",
        help_text="작성자"
    )
    due_date = models.DateTimeField(
        verbose_name="마감일",
        help_text="마감일"
    )
    completed = models.BooleanField(
        default=False,
        verbose_name="완료 여부",
        help_text="완료 여부"
    )
    created_at = models.DateTimeField(
        auto_now_add=True,
        blank=True,
        null=False,
        verbose_name="생성 일시",
        help_text="데이터가 생성된 날짜 시간"
    )
    updated_at = models.DateTimeField(
        auto_now=True,
        blank=True,
        null=False,
        verbose_name="수정 일시",
        help_text="데이터가 수정된 날짜 시간"
    )


    # verbose_name: 모델 객체의 이름으로 관리자 화면 등에서 표시됩니다.
    # verbose_name_plural: 영어를 기준으로 복수형입니다. 옵션을 지정하지 않으면 verbose_name에 s를 붙입니다.
    # ordering: '-created' 라는 필드를 기준으로 내림차순으로 정렬합니다.
    class Meta:
        verbose_name = '할일 목록'
        verbose_name_plural = '핧일 목록'
        ordering = ['-created_at']

    def __str__(self):
        return f"Todo {self.title}/{self.author}/{self.created_at}"

backend/models/init.py 파일내용은 아래와 같다.

from .todo import *

위 작업 후 Django 폴더 구조는 아래와 같다.


Django setting.py 설정

backend/config/settings.py 파일의 내용을 수정한다. 설치한 django 패키지와 생성한 todo 앱을 추가한다.

하단의 시간설정을 변경한다.


DB migration 실행

todo 앱 생성후 데이터베이스와 연동을 위해 migration을 실행한다. 데이터베이스는 기본값인 sqlite3를 사용한다.

$ python manage.py makemigrations 명령으로 migration 파일을 생성하겠습니다.
$ python manage.py migrate 데이터베이스 스키마 생성


DB 확인

django-extensions를 사용하여 Django model의 내용을 확인 할 수 있다. 

$ python manage.py shell_plus --print-sql --ipython

아래 파이썬 코드를 통해 데이터 확인이 가능하다.

# 전체 데이터 가져오기
Todo.objects.all() 

# 새로운 object 생성
Todo.objects.create(
	title = "hello todo list",
	description = "Hi desc",
	author = "tim",
	due_date=timezone.now()
)

# primary key 1인 데이터 가져오기
Todo.objects.get(pk=1)

# completed가 Falase인 데이터 모두 가져오기
Todo.objects.filter(completed=False)

Django REST Framework 설정

DRF 설정을 위해 생성할 폴더 및 파일은 아래와 같다.

backend/config/urls.py 수정
backend/todo/urls.py 생성
backend/todo/views 폴더 생성
backend/todo/views/todo.py 생성
backend/todo/views/__init__.py 생성
backend/todo/serializers 폴더 생성
backend/todo/serializers/todo.py 생성
backend/todo/serializers/__init__.py 생성

backend/config/urls.py

http://localhost:8000/admin/ 접속시 DRF 첫화면 연결하고 http://localhost:8000/api/ 접속시 todo.urls의 설정을 보여준다.

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

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('todo.urls'))  # http://localhost:8000/api/ 접속시 todo.url 참조
]

 

backend/todo/urls.py

http://localhost:8000/api/ 접속시 해당 파일에서 작업이 이루어진다. 

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

# viewset은 router를 사용하여 URL을 관리
router = DefaultRouter()  
router.register(r'todo', TodoModelViewSet)

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

 

backend/todo/views/todo.py

todo object 전체를 다루며 serializer를 사용하여 데이터를 json 형식으로 변환한다.

from rest_framework import viewsets
from todo.models import Todo
from todo.serializers.todo import TodoSerializer


class TodoModelViewSet(viewsets.ModelViewSet):
    queryset = Todo.objects.all()
    serializer_class = TodoSerializer

backend/todo/views/__init__.py

backend/todo/views 폴더내 여러 view가 존재한다면 추가로 작성해주면 된다.

from .todo import *

 

backend/todo/serializers/todo.py

from rest_framework import serializers
from todo.models import Todo


class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = ['id', 'title', 'description', 'author', 'due_date', 'completed']

backend/todo/serializers/__init__.py 

from .todo import *

 

DRF 설정 후 django 실행을 하고 http://127.0.0.1:8000/api/ 접속해본다.

$ python manage.py runserver

정상적으로 DRF를 사용한 django 서버가 작동한다.

http://127.0.0.1:8000/api/todo 로 접속하게 되면 모든 todo 데이터와 새로운 todo 입력이 가능하다.

http://127.0.0.1:8000/api/todo/1 로 접속하여 생성된 todo로 접근한다. 삭제와 수정이 가능하다.


Swagger 추가

설치한 drf_yasg를 설정하여 API 문서도 추가한다. backend/config/urls.py 에서 swagger에 대한 코드를 추가한다.

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

from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view( 
    openapi.Info( 
        title="Swagger Test API", 
        default_version="v1", 
        description="Swagger Test API 문서", 
        terms_of_service="https://www.google.com/policies/terms/", 
        contact=openapi.Contact(name="swagger test", email="swagger@swagger.com"), 
        license=openapi.License(name="swagger license"), 
    ), 
    public=True, 
    permission_classes=(permissions.AllowAny,), 
)

urlpatterns = [
    path('swagger<str:format>', schema_view.without_ui(cache_timeout=0), name='schema-json'),
    path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
    path('docs/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
 
    path('admin/', admin.site.urls),
    path('api/', include('todo.urls'))  # http://localhost:8000/api/
]

django 서버 실행 후 http://127.0.0.1:8000/swagger/ 접속시 아래와 같은 화면을 볼 수 있다.

http://127.0.0.1:8000/docs/ 접속 시 화면 API 문서가 완성되었다.