Vue 와 Django(DRF) 를 이용하여 Todo 리스트 만들기 - 2 (백엔드 Django Model)
Project/Django & Vue.js

Vue 와 Django(DRF) 를 이용하여 Todo 리스트 만들기 - 2 (백엔드 Django Model)

뉴비뉴 2020. 6. 7.

안녕하세요.

 

오늘은 투두 리스트에 사용 될 DB 스키마를 한번 작성하고, API Server까지 구현해보겠습니다.

 

Django DB 구조변경 및 DB 스키마 생성

먼저 구조를 간단하게 변경해주도록 하겠습니다.

구조를 변경하는 이유는 가독성, 다른 앱의 추가되었을 때의 재사용성 등등 입니다.

 

먼저 todo라는 앱 폴더 내에서 models와 views라는 폴더를 생성합니다.

그리고 그 안에 기존에 있던 models.py와 views.py를 이동시켜줍니다.

models.py 라는 모델 파일의 이름을 common.py 로 변경하고, 여기에 공통으로 사용될 수 있는 필드들을 정의하도록 하겠습니다.

models 폴더를 모듈로 사용하고 싶으면 __init__.py 를 생성하고, 안에 파일명을 적어두면 편리하게 사용할 수 있습니다.

# common.py

from django.db import models


class BaseModel(models.Model):
    """
    created_at, updated_at과 같은 자주사용하는 필드를 정의합니다.
    """
    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="데이터가 수정된 날짜입니다."
    )

    class Meta:
        abstract = True

다음으로 만들 기능의 메인인 될 todo 테이블을 생성해보겠습니다.

# todo.py

from django.db import models

from .common import BaseModel


class Todo(BaseModel):  # 필드와 그 옵션을 정의합니다.
    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="투두 완료 여부를 나타냅니다."
    )

    class Meta:
        verbose_name = '투두 리스트'
        verbose_name_plural = '투두 리스트(들)'
        ordering = ['-created_at']

    def __str__(self):
        return f"Todo-{self.author}-{self.created_at}"
  • max_length: 해당 필드의 최대 입력 가능한 문자열의 개 수를 제한합니다.
  • verbose_name: 입력하지 않으면 필드명으로 대신합니다.(언더스코어를 스페이스로 바꾸어서)
    verbose_name="" 으로 생성할 수도 있고, 상단에 " ", 으로도 생성할 수 있습니다.
    ex) models.CharField("벌보스네임", max_length=32)
  • Meta 클래스는 Django 모델의 내부 클래스입니다.
    • verbose_name: 모델 객체의 이름으로 관리자 화면 등에서 표시됩니다.
      해당 값을 지정하지 않으면 CamelCase 클래스 이름을 기준으로 todo 이와 같이 모두 소문자로 변경됩니다.
    • verbose_name_plural: 영어를 기준으로 복수형입니다.
      verbose_name_plural 옵션을 지정하지 않으면 verbose_name에 s를 붙입니다.
    • ordering: '-created' 라는 필드를 기준으로 내림차순으로 정렬합니다.
  • __str__() 메서드는 모델 클래스의 객체의 문자열 표현을 리턴합니다.
    이 메서드를 설정해주지 않으면 object ID?와 같은 정체를 알 수 없는 숫자가 나오게 됩니다.
    {self.author} 는 정의한 필드를 호출하여 사용하는 것 입니다. created_at은 없는데 어디서 나온거지? 라는 생각을 하실 수도 있으실텐데 이 부분은 BaseModel을 상속받아 사용했기에 그 내부 필드를 사용한 것 입니다.
# __init__.py

from .common import *
from .todo import *

 

좋습니다. 투두 리스트를 작성하는데 필요한 DB 스키마를 완성했습니다.

아차 참고로 Django는 테스트를 위해 db.sqlite3를 제공해줍니다. 그리고 기본적으로 그것을 바라보도록 설정이 되어있습니다.

추후에 다른 DB를 사용하고자한다면 해당 부분을 변경하면 되겠죠?

자 이제 makemigrations, migrate 명령어를 살펴보겠습니다. 이러한 명령어는 models.py에 정의된 모델의 생성/변경 내역을 히스토리 관리, 데이터베이스에 적용 등과 같은 기능을 제공하여 손쉽게 데이터베이스의 구조를 바꿀 수 있습니다.

 

$ python manage.py makemigrations 명령으로 migration 파일을 생성하겠습니다.

migration 폴더에 생성되었습니다.

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

근데 뭔가 이상합니다. 나는 분명 맨 아래 todo 만 생성하여 적용했는데...?

여기서 전 편에서 말씀드렸던 기본적으로 제공해주는 테이블(세션, 계정, 등등)도 DB 에 적용이 된 것이라고 생각하시면 됩니다.

 

데이터 다루기

이제 데이터베이스에 테스트로 투두를 한번 작성해보겠습니다. 작성할 수 있는 방법은 정말 다양합니다.

실제 로직을 짜서 작성하는 방법도 있고, Django Shell 로 접속하여 데이터를 확인하는 방법도있고, Admin 파일을 등록하여 데이터를 확인하는 방법도 있습니다. 사실 Admin 파일을 등록하여 데이터를 확인하고 생성하는 방법이 가장 쉬운데 우리는 전편에서 requirements.txt에 포함시켰던 django_extension 를 활용해보기 위해 Django Shell_plus 로 접속하여 데이터를 생성하고, 확인해보도록 하겠습니다.

 

django_extension

$ python manage.py shell_plus 로 현재 프로젝트의 쉘에 접속할 수 있습니다.

여기서 몇가지 장점이 보이는데 가장 좋은 점은 사용 안할수도 있지만 내가 생성한 models와 각종 쿼리를 입력할 때 필요한 함수들을 import 해준다는 것 입니다. 이 외에도 IPython 을 설치하여 사용할 수도 있고, jupyter, 그리고 쿼리문도 상세하게 볼 수 있습니다.

$ pip install ipython

$ python manage.py shell_plus --ipython

ipython 으로 실행 된 shell 모습

$ python manage.py shell_plus --print-sql

$ Todo.objects.all() 

나중에 내가 짠 쿼리가 왜 느리지? 할 때 디버깅용으로도 간단하게 사용할 수 있습니다.

자 그럼 데이터를 생성해보겠습니다.

장고 ORM은 많은 기능들을 제공해주는데 투두 리스트의 간단한 CRUD를 테스트하기 위한 것들만 간단하게 설명하겠습니다.

모든지 하면서 설명하는게 최고니 간단하게 투두를 하나 만들어보겠습니다.

timezone 에서 오류가 나시는 분들은 from django.utils import timezone 을 해주시면 됩니다.

  • <TableName>.objects.create()  # 테이블 이름, 곧 models 파일의 class Name 을 적어주면 됩니다.
  • create() 안에 정의 된 것들은 필드=Value 입니다. models 파일에 정의한 대로 데이터형식을 맞춰줘야 합니다.
    ex) Datetype 이면 timezone.now() 처럼 데이트타입의 값을 입력해주어야 합니다.
  • complated 라는 필드는 정의를 하지 않았지만 알아서 생성된 것을 확인할 수 있습니다.
    사진의 values의 가장 마지막 줄 , 0 -> 여기서 말하는 0은 False이고 디폴트로 0이라는 값을 주었기 때문에 값을 입력하지 않아도 알아서 생성이 되었습니다.
  • 사진의 가장 마지막 줄에 나온 것은 정상적으로 생성이 되었다는 것이고, __str__ 메서드에서 정의해주었던 값이 출력된 것을 확인할 수 있습니다!

이제 쿼리문을 이용하여 한번 필드를 살펴보겠습니다.

Todo 테이블의 모든 데이터를 보고 싶다면 all() 을 사용하면되고, 특정 데이터 한 개를 지정하여 가져오고 싶다면 get(), 조건을 걸어 해당 조건에 적합한 것들만 가져오고 싶다면 filter()를 사용하면 됩니다.

# get
>>> todo = Todo.objects.get(pk=1)
>>> todo.author
'Tim'

# filter
>>> todos = Todo.objects.filter(complated=False)
>>> for todo in todos:
>>> 	todo.author
'Tim'

 

ORM 을 다루는 방법은 공식문서를 확인하시면 될 거 같습니다.

 

자 이제 Todo라는 테이블이 생성되었습니다.

 

다음시간에는 REST API로 서버를 설정해보겠습니다.

 

Reference

https://brownbears.tistory.com/443

댓글

💲 추천 글