본문 바로가기

Pyhon/Django

[Pyhon/Django] 장고 기초#005. 장고 모델(Model) 생성

장고 모델(Model)

모델은 장고에서 사용되는 객체(Object)의 특별한 정의입니다. 일반적으로 객체란 OOP(객체 지향 프로그래밍, Object-Oriented Programming)에서 의미하는 인스턴스에 대한 정의입니다. 고양이(Cat 클래스) 객체는 털 색상(fur_color 멤버 변수), 몸무게(weight 멤버 변수), 나이(age 멤버 변수), 밥을 먹다(Eat 멤버 함수), 휴식하다(Rest 멤버 함수) 등으로 정의 할 수 있습니다. 장고의 모델은 이러한 객체 중 특별한 목적을 지닌 것을 뜻합니다.

  • ORM(Object Relational Mapping) 기반으로 데이터베이스(Table)와 객체(Class)를 자동으로 맵핑(Mapping)한다.
  • ORM을 위한 객체의 속성(Properties)과 역할(Methods)을 스키마(Schema)로 정의한다.

애플리케이션(Application) 생성

이제부터는 아래 첨부 된 링크의 문서를 참고합니다. 해당 링크에서는 장고 프로젝트의 설치부터 시작하여 지금 진행하는 모델, 앞으로 진행하게 될 URL, 뷰, ORM 등에 대한 내용을 튜토리얼로 다루고 있습니다. 장고를 학습하기 위해서는 해당 프로젝트의 튜토리얼 소스 코드로 충분하며, 부족한 내용에 대해서만 부연 설명을 추가하는 방향으로 진행하겠습니다.

https://tutorial.djangogirls.org/ko/

 

들어가며 · HonKit

1차 : 2015. 10. 1. 이수진, 함기훈, 박제권, 조혜선, 정광윤, 임정훈, 문지영, 김휘경, 송석리, 여형석, 심혜민

tutorial.djangogirls.org

내 프로젝트(helloWorld)에서 애플리케이션을 생성합니다. 기존과 같이 터미널을 사용해도 무관하나, 보통 IDE에서 터미널 기능을 제공하므로 파이참의 터미널을 사용하도록 하겠습니다.

파이참의 하단 툴바에서 [Terminal]에 들어갑니다. 다음 커맨드(ls)를 입력하면 IDE에서 터미널의 디폴트 경로가 프로젝트 폴더인 것을 확인 할 수 있습니다. 터미널을 새로 열었을 때 장고 프로젝트 경로로 이동 할 필요가 없으므로, IDE에서 제공하는 터미널을 사용하는 것이 훨씬 편리합니다. 

$ ls
db.sqlite3      helloWorld      manage.py

터미널에서 블로그(blog) 애플리케이션을 생성(startapp)합니다. 

$ python3 manage.py startapp blog

커맨드가 정상적으로 처리되면, 별도의 출력 없이 blog 디렉토리가 생성 된 것을 확인 할 수 있습니다. IDE에서는 왼쪽 프로젝트 파일 트리를 왼쪽 클릭하거나 오른쪽 클릭하여 [Reload from Disk]를 실행하여 변경 사항을 IDE에 반영합니다.

모델 생성

블로그 애플리케이션을 생성하였다면, 블로그에 포스팅을 위한 글(Post) 모델을 생성합니다. 글 모델을 생성한다는 것은, 블로그 애플리케이션에서 글을 작성(Create), 수정(Update), 삭제(Delete), 읽기(Read)하기 위한 CRUD(Create, Read, Update, Delete)를 ORM으로 자동화 하겠다는 것을 의미합니다. 

blog/models.py 스크립트를 열어 다음과 같이 내용을 수정합니다.

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


class Post(models.Model):
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField()
    created_date = models.DateTimeField(
            default=timezone.now)
    published_date = models.DateTimeField(
            blank=True, null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title

 

작성한 소스 코드는 다음과 같이 해석 할 수 있습니다.

  • from / import는 다른 패키지(스크립트)의 기능을 가져와서 사용하기 위함입니다.
  • class Post는 글(Post) 모델(class)를 정의하는 것이며, 모델은 반드시 알파벳 대문자로 시작해야 합니다.
  • author, title, text, ...와 같은 멤버 변수는 ORM으로 데이터베이스에 생성되는 Post 테이블에 대한 스키마입니다.
  • 나머지 코드에 대해서는 당장 중요하지 않으므로 생략합니다.

데이터베이스 마이그레이션

우선 blog/models.py의 수정 사항을 저장하기 위해서 상단 툴바의 [File > Save All]를 클릭합니다. 다음으로 터미널로 이동하여 블로그 애플리케이션의 마이그레이션 파일을 생성(makemigrations)합니다.

$ python3 manage.py makemigrations blog
Migrations for 'blog':
  blog/migrations/0001_initial.py
    - Create model Post

블로그 애플리케이션의 마이그레이션 파일을 최초로 생성했기 때문에, blog/migrations 디렉토리가 새로 추가되었습니다. 터미널 출력 내용을 보면 blog/migrations/0001_initial.py가 생성 된 것을 확인 할 수 있습니다. 0001_initial.py 스크립트를 열면 다음과 같이 models.py에서 정의한 모델의 생성과 관련된 내용을 확인 할 수 있습니다.

operations = [
        migrations.CreateModel(
            name='Post',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=200)),
                ('text', models.TextField()),
                ('created_date', models.DateTimeField(default=django.utils.timezone.now)),
                ('published_date', models.DateTimeField(blank=True, null=True)),
                ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
            ],
        ),
    ]

다시 터미널에 들어가서 블로그 애플리케이션을 마이그레이션(migrate) 합니다. 출력 내용을 확인하면 0001_initial.py 마이그레이션 파일이 적용 된 것을 통해 마이그레이션 디렉토리(blog/migrations) 내 변경 사항을 모두 읽어 적용한다는 것을 알 수 있습니다.

python3 manage.py migrate blog
Operations to perform:
  Apply all migrations: blog
Running migrations:
  Applying blog.0001_initial... OK

마이그레이션이 완료되면 이제 로컬 데이터베이스에 Post 테이블이 생성되었습니다. 이를 확인하기 위해서는 터미널에서 현재 장고 프로젝트에 연결 된 sqlite3를 실행합니다.

$ python3 manage.py dbshell
$ .databases
/Users/namepgb/Desktop/Django/Projects/helloWorld/db.sqlite3
$ .tables
auth_group                  blog_post                 
auth_group_permissions      django_admin_log          
auth_permission             django_content_type       
auth_user                   django_migrations         
auth_user_groups            django_session            
auth_user_user_permissions
$ select sql from sqlite_master where name='blog_post';
CREATE TABLE "blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(200) NOT NULL, "text" text NOT NULL, "created_date" datetime NOT NULL, "published_date" datetime NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED)

테이블 확인(.tables) 시 blog_post(블로그 애플리케이션_글 모델)에 해당하는 테이블이 생성되었으며, 스키마를 확인하면 내가 작성한 소스 코드의 멤버 변수와 일치하는 것을 확인 할 수 있습니다. 데이터베이스가 현재 프로젝트에 연결(.databases)되어있으므로, 데이터베이스 지정 없이 sqlite3를 실행하면 위 테이블을 확인 할 수 없습니다. 장고 프로젝트를 진행하는 동안 데이터베이스는 반드시 (manage.py)를 통해서 접속해야 함에 주의하시기를 바랍니다.