[DJANGO]튜토리얼② - 데이터베이스

박민하·2022년 6월 1일
1

PROJECT

목록 보기
2/17
post-thumbnail

이 포스팅은 Django 사이트의 튜토리얼을 정리한 글이다.


✅ 데이터베이스 설치

  mysite/settings.py 파일은 Django 설정을 모듈 변수로 표현한 보통의 Python 모듈이다. 기본적으로는 SQLite을 사용하도록 구성되어 있다. SQLite를 사용한다면 아무것도 미리 생성할 필요 없이 필요할 때마다 데이터베이스 파일이 자동으로 생성된다.

  mysite/settings.py를 편집할 때, 현재 시간대에 맞춰 TIME_ZONE 값을 설정한다. 또한, 이 파일의 윗쪽에 있는 INSTALLED_APPS 파일은 현재 Django 인스턴스에서 활성화된 모든 Django 어플리케이션들의 이름이 담겨 있다. 앱들은 다수의 프로젝트에서 사용될 수 있고, 다른 프로젝트에서 쉽게 사용될 수 있도록 패키징하여 배포할 수 있다.

✔ INSTALLED_APPS

  기본적으로 INSTALLED_APPS는 Django와 함께 일반적인 경우에 사용하기 편리하도록 다음의 앱들이 제공된다.

  • django.contrib.admin : 관리용 사이트.
  • django.contrib.auth : 인증 시스템.
  • django.contrib.contenttypes : 컨텐츠 타입을 위한 프레임워크.
  • django.contrib.sessions : 세션 프레임워크.
  • django.contrib.messages : 메세징 프레임워크.
  • django.contrib.staticfiles : 정적 파일을 관리하는 프레임워크.

  이러한 기본 어플리케이션들 중 몇몇은 최소한 하나 이상의 데이터베이스 테이블을 사용하는데, 그러기 위해서는 데이터베이스에서 테이블을 미리 만들 필요가 있다. 이를 위해, 다음의 명령을 실행해보자.

✔ migrate

$ python manage.py migrate`

  migrate 명령어는 INSTALLED_APPS 설정을 확인하고, mysite/settings.py 파일의 데이터베이스 설정 및 앱과 함께 제공된 데이터베이스 마이그레이션에 따라 필요한 데이터베이스 테이블을 생성한다.

✅ Model 만들기

  여기서 모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조(layout)를 말한다. 지금 진행하는 의견조사 앱에서는 질문과 선택이라는 두 가지 모델을 만들것이다.

  • 질문에는 질문과 게시 날짜가 있다.
  • 선택에는 선택 텍스트와 투표 집계라는 두 가지 필드가 있다. 각 선택 항목은 질문과 연결된다.

  이러한 개념은 Python 클래스로 표현된다. 다음과 같이 polls/models.py 파일을 편집하자.

# polls/models.py
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

  여기서 각 모델은 django.db.models.Model를 하위 분류하는 클래스로 표현된다. 각 모델에는 여러 클래스 변수가 있으며, 각 클래스 변수는 모델의 데이터베이스 필드(컬럼, 열)를 나타낸다.

1. Field 인스턴스 - "CharField", "DateTimeField"

  데이터베이스의 각 필드는 Field 클래스의 인스턴스(객체)로서 표현된다. CharField 는 문자(character) 필드를 표현하고, DateTimeField 는 날짜와 시간(datetime) 필드를 표현한다. 이것은 각 필드가 어떤 자료형을 가질 수 있는지를 Django 에게 말해줍니다.

2. Field 인스턴스 이름 - "question_text", "pub_date"

  각각의 Field 인스턴스의 이름(question_text 또는 pub_date)은 기계가 읽기 좋은 형식(machine-friendly format)의 데이터베이스 필드 이름이다. 이 필드명을 Python 코드에서 사용할 수 있으며, 데이터베이스에서는 컬럼명으로 사용할 것이다.

# machine-friendly? human-readable?

  Field 클래스의 생성자에 선택적인 첫번째 위치 인수를 전달하여 사람이 읽기 좋은(human-readable) 이름을 지정할 수도 있다. 이 방법은 Django 의 내부를 설명하는 용도로 종종 사용되는데, 이는 마치 문서가 늘어나는 것 같은 효과를 가진다. 만약 이 선택적인 첫번째 위치 인수를 사용하지 않으면, Django 는 기계가 읽기 좋은 형식의 이름을 사용한다. 이 예제에서는 Question.pub_date 에 한해서만 인간이 읽기 좋은 형태의 이름을 정의하고, 그 외의 다른 필드들은 기계가 읽기 좋은 형태의 이름이라도 사람이 읽기에는 충분하다

3. Field 클래스 인수 - "max_length","default=0"

  몇몇 Field 클래스들은 필수 인수가 필요하다. 예를 들어, CharField 의 경우 max_length 를 입력해 주어야 한다. 이것은 데이터베이스 스키마에서만 필요한것이 아닌 값을 검증할때도 쓰인다.

  또한 Field 는 다양한 선택적 인수들을 가질 수 있다. 이 예제에서는, default 로 하여금 votes 의 기본값을 0 으로 설정했다.

3. ForeignKey를 사용한 관계설정

  이 예제에서는 각각의 Choice 가 하나의 Question 에 관계된다는 것을 Django 에게 알려준다. Django 는 다-대-일(many-to-one), 다-대-다(many-to-many), 일-대-일(one-to-one) 과 같은 모든 일반 데이터베이스의 관계들를 지원한다.

✅ Model 활성화

  Django는 모델에 대한 정보를 가지고 다음과 같은 일을 할 수 있다.

  • 이 앱을 위한 데이터베이스 스키마 생성(CREATE TABLE 문)
  • Question과 Choice 객체에 접근하기 위한 Python 데이터베이스 접근 API를 생성

  그러나, 가장 먼저 현재 프로젝트에게 polls 앱이 설치되어 있다는 것을 알려야 한다.

1. INSTALLED_APPS에 polls 추가

  앱을 현재의 프로젝트에 포함시키기 위해서는 앱의 구성 클래스에 대한 참조를 INSTALLED_APPS 설정에 추가해야 한다. PollsConfig 클래스polls/apps.py 파일 내에 존재한다(파이썬 경로는 polls.apps.PollsConfig가 된다). 이 점으로 구분된 경로를 mysite/settings.py 파일을 편집하여 INSTALLED_APPS 설정에 추가하면 된다.

# mysite/settings.py
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

  이제, Django는 polls 앱이 포함된 것을 알게 되었다!

2. 변경사항에 대한 마이그레이션 만들기

  다음으로 이 명령을 내려보자.

$ python manage.py makemigrations polls

  makemigrations 을 실행시킴으로서 앞서 모델을 변경시킨 사실과(이 경우에는 새로운 모델을 만들었다) 이 변경사항을 migration으로 저장시키고 싶다는 것을 Django에게 알려준다.

  마이그레이션은 Django가 모델(및 데이터베이스 스키마)에 대한 변경 사항을 저장하는 방법이다. 원하는 경우 새 모델에 대한 마이그레이션을 읽을 수도 있다(polls/migrations/0001_initial.py). Django가 만들 때마다 읽을 수는 없지만, Django가 변경하는 방식을 수동으로 조정하려는 경우에 대비하여 사람이 편집할 수 있도록 설계되어있다.

  migration들을 실행시켜주고, 자동으로 데이터베이스 스키마를 관리해주는 migrate 명령어가 있다. 이 명령을 알아보기 전에 migration이 내부적으로 어떤 SQL 문장을 실행하는지 살펴보자. sqlmigrate 명령은 migration 이름을 인수로 받아, 실행하는 SQL 문장을 보여준다.

$ python manage.py sqlmigrate polls 0001`

  이미지의 결과를 다듬으면 아래와 같다.

BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL,
    "question_id" integer NOT NULL
);
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");

COMMIT;

"참고"

  • 사용하는 데이터베이스에 따라서 출력결과는 다를 수 있다. 위의 출력결과는 PostgreSQL에서 생성됐다.
  • 테이블 이름은 앱의 이름모델의 이름(소문자)이 조합되어 자동 생성된다. 이 경우 앱의 이름인 polls 와 소문자로 표기된 모델의 이름인 question 과 choice가 합쳐진다(이 동작을 재지정(override)하여 수정할 수 있다).
  • 기본 키(ID)가 자동으로 추가된다(이 동작도 재지정 가능).
  • 관례에 따라, Django는 외래 키 필드명에 "_id" 이름을 자동으로 추가한다(재지정 가능).
  • 외래 키 관계는 제약 조건에 의해 명시된다. 트랜잭션이 끝날 때까지 외래 키를 적용하지 않도록 PostgreSQL에 지시한다.
  • 사용하는 데이터베이스에 따라 데이터베이스 고유의 필드타입이 조정된다. 따라서, 자동 증가 필드를 생성할 경우 auto_increment(MySQL), serial(PostgreSQL), integer primary key autoincrement(SQLite)와 같이 사용하는 데이터베이스에 따라 적절한 필드타입이 자동으로 선택된다. 필드 명에 사용되는 인용부호도 상황에 따라 겹따옴표나 홑따옴표가 적절히 선택된다.
  • 이 sqlmigrate명령은 실제로 데이터베이스에서 마이그레이션을 실행하지 않는 대신 SQL Django가 필요하다고 생각하는 것을 보여준다. Django가 수행할 작업을 확인하거나 변경을 위해 SQL 스크립트가 필요한 경우에 유용하다.

3. 변경사항을 데이터베이스에 적용하기

  이제 migrate 를 실행시켜 데이터베이스에 모델과 관련된 테이블을 생성해보자.

$ python manage.py migrate

  migrate 명령은 아직 적용되지 않은 마이그레이션을 모두 수집해 이를 실행하며(Django는 django_migrations 테이블을 두어 마이그레이션 적용 여부를 추적한다), 이 과정을 통해 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어진다.

  마이그레이션은 매우 기능이 강력하여, 마치 프로젝트를 개발할 때처럼 데이터베이스나 테이블에 손대지 않고도 모델의 반복적인 변경을 가능하게 해준다. 동작 중인 데이터베이스를 자료 손실 없이 업그레이드 하는 데 최적화 되어 있다.

✅ API 다뤄보기

  대화식 Python 쉘에 뛰어들어 Django API를 자유롭게 다뤄보다. Python 쉘을 실행하려면 다음의 명령을 입력한다.

$ python manage.py shell`

  단순히 《python》이라고 입력하는 대신 위의 명령어를 입력하는 이유는 manage.py은 Django에게 mysite/settings.py 파일의 경로를 제공하는 DJANO_SETTINGS_MODULE 환경 변수를 설정하기 때문이다.

  아래는 쉘에 진입 후 이것저것 실행해본 결과다. exit() 을 입력하면 쉘에서 나갈 수 있다.

  여기서 빨간 박스로 표시한 Question: Question object (1)은 이 객체를 표현하는 데 별로 도움이 되지 않는다. polls/models.py 파일의 Question 모델을 수정하여 __str__() 메소드를 Question과 Choice에 추가해 보자.

# polls/models.py
from django.db import models

class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text

  __str__() 메소드를 추가하는것은 객체의 표현을 대화식 프롬프트에서 편하게 보려는 이유 말고도, Django 가 자동으로 생성하는 관리 사이트에서도 객체의 표현이 사용되기 때문이다.

  이 모델에 커스텀 메소드도 추가해보자.

# polls/models.py
import datetime

from django.db import models
from django.utils import timezone


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

  이하는 모두 추가한 결과물이다.

  변경된 사항을 저장하고 다시 python manage.py shell을 실행해보자.

✅ 관리자 생성하기

  관리 사이트에 로그인 할 수 있는 사용자를 생성해 보자.

$ python manage.py createsuperuser`

  원하는 username과 이메일, 암호 2회를 입력하면 된다.

✔ 개발 서버 시작

  Django 관리자 사이트는 기본으로 활성화되어 있다. 서버가 동작하고 있지 않다면 다음 명령으로 시작하면 된다.

$ python manage.py runserver

  이제, 웹 브라우져를 열고 로컬 도메인의 《/admin/》으로 이동하자. 예를 들면, http://127.0.0.1:8000/admin/ 으로 접근할 수 있다. 그럼 다음과 같이 로그인 화면이 보일 것이다.

✔ 관리자 사이트에 들어가기

  앞서 생성한 슈퍼유저(superuser) 계정으로 로그인하면 다음과 같은 Django 관리 인덱스 페이지가 보인다.

  편집 가능한 그룹과 사용자와 같은 몇 종류의 컨텐츠를 볼 수 있다. 이것들은 django.contrib.auth 모듈에서 제공되는데, Django 에서 제공되는 인증 프레임워크다.

✔ 관리 사이트에서 poll app 을 변경가능하도록 만들기]

  poll app 이 관리 인덱스 페이지에서 보이지 않는다. polls/admin.py 파일을 열고 Question objects 에 admin interface가 있다고 알리자.

# polls/admin.py
from django.contrib import admin
from .models import Question
admin.site.register(Question)

✔ 자유로운 관리 기능을 탐색하기

  Question 을 등록시켰다면 Django 는 이를 알아채고 관리 인덱스 페이지에 이를 표시할것이다.

  《Questions》 을 클릭하면 질문들을 위한 《change list》 로 이동한다. 이 페이지는 데이터베이스에 저장된 모든 질문들을 보여주며, 그 중 하나를 선택하여 변경할 수 있다. 이전에 등록했던 《What’s up?》 질문이 있을 것이다. 《What’s up?》 질문을 클릭하여 수정도 가능하다.

"여기서 알아둘 것들:"

  • 이 서식은 Question 모델에서 자동 생성됐다.
  • 모델의 각 필드 유형들은(DateTimeField, CharField) 적절한 HTML 입력 위젯으로 표현된다. 각각의 DateTimeField 는 JavaScript 로 작성된 단축 기능과 연결된다. 날짜는 《Today》버튼과 달력 팝업에서 입력할 수 있으며, 시간은 《Now》버튼과 일반적으로 입력하는 시간들을 제공하는 편리한 팝업을 통해서도 입력할 수 있다.

"페이지의 아래 부분에서 다음과 같은 몇가지 옵션을 제공한다:"

  • 저장(Save) : 이 유형의 객체에 대한 변경사항을 저장하고, 변경된 목록 페이지를 보여준다.
  • 저장 및 편집 계속(Save and continue editing) : 이 객체에 대한 변경사항을 저장하고, 현재 편집창을 갱신한다.
  • 저장 및 다른 이름으로 추가(Save and add another) : 변경사항을 저장하고, 이 유형의 객체에 대한 비어있는 새로운 입력창을 불러온다.
  • 삭제(Delete) : 삭제를 확인하는 페이지를 띄운다.

  만약 《Date published》 값이 Tutorial 1 에서 질문을 생성했을때의 시간과 일치하지 않는다면 TIME_ZONE(시간대) 설정을 빼먹은 걸지도 모른다. 이 설정을 바꾸시고 다시 페이지를 불러오시면 올바른 값이 표현된다.

  《Date published》 의 값을 《Today》와《Now》 단축버튼을 눌러 바꾼 후, 《Save and continue editing》을 누르고 우측 상단의 《History》 버튼을 눌러라. Django 관리사이트를 통해 누가(username) 언제(timestamp) 무엇을 바꿨는지 목록을 확인할 수 있다.

profile
backend developer 🐌

0개의 댓글