터칭 데이터
장고(Django) 모델(Model)만들기 본문
장고에서 모델이 뭐죠?
웹 페이지는 데이터 베이스(DB)에 저장된 데이터를 가져와 표현됩니다.
장고에서는 DB를 쉽고 빠르게 사용할 수 있는 모델이라는 기능을 제공합니다.
모델은 DB를 테이블별로 읽어서 테이블들마다 저장된 데이터들을 코드에서 읽을 수 있도록 도와주는 기능입니다.
이런 기능을 ORM이라고도 부릅니다.
첫번째 모델을 만들고 테이블도 만들어 실습을 진행해봅시다.
우리의 계획은 다음과 같습니다.
- 모델을 생성한다.
- 모델을 테이블에 적용해 사용하기 위해 마이그레이션을 만든다.
- 이렇게 생성하고 마이그레이션을 거친 모델을 이용해 테이블을 만든다.
마이그레이션 등 생소한 개념이 있지만 이제 학습을 진행하며 알아가도록 하겠습니다.
어떤 테이블을 만들까요?
여름 휴가에 대해 설문조사를 할 수 있는 테이블을 만들어 봅시다.
질문: 여름에 어디로 휴가를 갈래?
선택지: 산, 강, 바다, 도심 호캉스 등
질문을 저장하는 테이블A, 그리고 그 테이블A 보관된 질문에 해당되는 선택지들을 보관하는 테이블 B를 만듭니다.
테이블A
"여름에 어디로 휴가 갈래?", "커피 vs 녹차", ...
테이블B
"산, 강, 바다, 도심 호캉스", "커피, 녹차", ...
자 이제 테이블A와 테이블B를 만들기 위해 모델을 만들어봅시다.
모델 만들기
polls/models.py에
from django.db import models
# Create your models here.
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)
models.Model을 상속 받은 클래스 2개를 만들어 줍니다.
Question은 위에서 예시로 든 테이블 A,
Choice는 위에서 예시로 든 테이블 B입니다.
Choice 클래스의 question 변수는 설문&선택지의 특성상 Choice 테이블이 Question 테이블을 반드시 참조해야하기 때문에 이를 위해(즉, 참조를 할 수 있도록 해주기 위해) ForeignKey 메서드를 이용해 만든 변수입니다.
이렇게 polls 앱의 models.py파일에서 만들어진 클래스 Question과 Choice은 모델입니다.
모델과 테이블은 1:1로 대응한다 했습니다. 우리가 만든 클래스가 2개이니 테이블도 2개가 만들어질 것입니다.
이 모델을 마이그레이션 과정을 거쳐 데이터 베이스의 테이블이 되도록 하는 것이 이번 학습의 목표입니다.
마이그레이션(Migration)
1. 마이그레이션을 만들기 전에는 앱을 등록해줘야 합니다.
장고는 설치된 앱에 대해서만 마이그레이션을 진행하기 때문입니다.
이 앱의 등록은 어디서 진행할까요?
mysite/settings.py에 INSTALLED_APPS의 리스트 안에
INSTALLED_APPS = [
"polls.apps.PollsConfig",
...
...
]
와 같이 polls.apps.PollsConfig를 입력해 앱을 등록하시면 됩니다.
polls.apps.PollsConfig는 어디에서 나왔을까요
바로 우리가 모델을 만들었던 앱인 polls의 app.py 파일의 AppConfig를 상속 받아 만들어져있던 클래스의 이름으로
PollsConfig를 향한 mysite/settings.py의 상대경로였습니다.
2. 앱을 등록했으니 마이그레이션을 진행한다.
터미널에서 아래와 같이 입력합니다.
python manage.py makemigrations polls
(DjangoProjects) C:\Users\User\DjangoProjects\Scripts\mysite>python manage.py makemigrations polls
Migrations for 'polls':
polls\migrations\0001_initial.py
- Create model Question
- Create model Choice
polls에 대해 Question과 Choice라는 테이블을 만들었다는 문구가 뜨면 성공입니다.
우리가 지금 진행한 마이그레이션의 내용을 살펴보려면
python manage.py sqlmigrate polls 0001
를 입력합니다.
(DjangoProjects) C:\Users\User\DjangoProjects\Scripts\mysite>python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE
"polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"question_text" varchar(200) NOT NULL,
"pub_date" datetime NOT NULL);
--
-- Create model Choice
--
CREATE TABLE
"polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL,
"question_id" bigint NOT NULL REFERENCES
"polls_question" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
SQL문으로 어떻게 작성했는지 확인할 수 있습니다.
그런데 우리가 만들지 않은 것들이 2개 있습니다.
첫번째, 우리가 넣지 않은 id라는 컬럼(필드)이 NOT NULL과 PRIMARY KEY, AUTOINCREMENT 옵션으로 만들어져 있는데 이는 장고에서 마이그레이션을 진행할 때 자동으로 추가해주는 컬럼입니다.
두번째, CREATE INDEX ~ 가 실행되었습니다. 왜일까요? Questions의 질문에는 Choice의 선택지들이 붙어있는 형태이기 때문에 앞으로 우리는 Question의 id를 이용해 Choice를 많이 조회할 것입니다. 그런데 만약 인덱싱이 미리 되어있지 않다면 Choice를 조회하는 매번 모든 테이블들을 풀스캔하게 됩니다. 하지만 미리 위와 같이 외래키(Foreign Key)에 대해 인덱싱을 진행해두면 그럴 필요가 사라지게 됩니다.
3. 이제는 테이블을 만들어보자
모델을 만들었고
앱을 등록했고
마이그레이션을 진행했습니다.
이제 테이블을 만들어봅시다.
python manage.py migrate
위와 같이 명령어를 입력합니다.
(DjangoProjects) C:\Users\User\DjangoProjects\Scripts\mysite>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
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 auth.0012_alter_user_first_name_max_length... OK
Applying polls.0001_initial... OK
Applying sessions.0001_initial... OK
그런데 뭔가 이상합니다.
빨간색 박스를 보면 우리는 분명 polls에 대한 모델만 만들고 polls에 대해서만 마이그레이션을 진행했는데
admin, auth, contenttypes, sessions 등의 작업이 같이 적용되었습니다.
이는 아까 우리가 마이그레이션에 앞서 polls 앱을 mysite/setting.py에 등록할 때 INSTALLED_APPS에 이미 있던 다른 앱들에 대한 작업도 같이 진행되기 때문입니다. 크게 신경쓰실 필요는 없습니다.
우리는 위의 터미널 이미지에서 파란색 박스안의 출력문대로 polls.0001_initial에 대한 작업이 잘 진행됐는지 확인해주면 됩니다.
이렇게 테이블 생성 작업까지 끝나고 한번 더 명령문을 입력하면
python manage.py migrate
(DjangoProjects) C:\Users\User\DjangoProjects\Scripts\mysite>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
No migrations to apply.
더 진행할 마이그레이션이 없다고 뜹니다.
우리는 바로 직전에 마이그레이션으로 테이블 생성을 마쳤기 때문입니다.
모델을 만들고
앱을 등록했고
마이그레이션을 만들었고
마이그레이트를 통해 테이블을 (반영)만들었습니다.
'장고 (Django)' 카테고리의 다른 글
장고(Django) 어드민(Admin) 계정 생성하고 관리하기 (0) | 2023.10.31 |
---|---|
장고(Django) 모델을 수정, 마이그레이션 되돌리기 (0) | 2023.10.31 |
장고(Django) App 생성하기 (0) | 2023.10.27 |
장고(Django) 프로젝트 생성하기 (0) | 2023.10.27 |
가상환경 설치 - Windows (0) | 2023.10.27 |