첫 번째 Django 앱 만들기! part1

예제로 배워봅시다.

우리는 이 튜토리얼을 통하여, 기초적인 투표 애플리케이션을 만들어 나갈 것입니다.

이 애플리케이션은 두 부분으로 구성됩니다.

  • 공개된 사이트는 사람들이 투표내용을 볼 수 있으며 투표에 참여할 수 있습니다.
  • 관리자 사이트는 당신(관리자)이 설문조사에 대하여 추가, 수정, 삭제를 할 수 있습니다.

우리는 여러분이 이미 Django 설치를 완료하였다고 가정하에 진행하도록 하겠습니다. 여러분은 파이썬 인터프리터를 실행하여 import django를 입력해 봄으로써 Django가 설치되어 있는지 확인할 수 있습니다. 만약 에러 없이 실행된다면, Django 설치가 완료된 것입니다.

도움을 어디서 받을수 있을까요?

만약 여러분이 이 튜토리얼을 따라하는 도중 문제가 발생할 경우
django-users로 메시지를 보내 주시거나 또는 #django on irc.freenode.net에서 당신에게 도움을 줄 다른 Django 사용자와 채팅을 할 수 있습니다.

프로젝트 만들기

만약 Django를 처음으로 사용한다면, 몇 가지 초기 설정에 신경써야 합니다. 즉, 여러분은 Django project를 구축하는데 몇 가지 자동 생성되는 코드를 필요로 합니다 – Django의 인스턴스를 위한 세팅들(데이터베이스 설정을 포함), Django의 특별한 옵션과 애플리케이션의 특별한 설정들입니다.

명령행에서, cd 디렉토리(여러분이 코드를 저장하고자 하는 디렉토리)로 이동 후 다음의 명령을 실행하세요.

django-admin.py startproject mysite

이것은 현재 위치한 디렉토리에 mysite 라는 디렉토리를 생성합니다.

django-admin 스크립트의 이름은 배포 패키지에 따라 다를 수 있습니다.

만약 여러분이 리눅스 배포판 패키지 관리자를 이용하여 Django를 설치 하였다면 (e.g. apt-get or yum) django-admin.py 파일의 이름이 django-admin로 변경되었을 수도 있습니다. 그럴 경우 여러분은 이 문서에서 계속적으로 각 명령에 .py을 생략하여 사용할 수 있습니다.

Mac OS X 권한

만약 여러분이 Mac OS X를 사용한다면, 여러분은 django-admin.py startproject를 실행할 때 “permission denied” 메시지를 볼 수 있을 것입니다. OS X와 같은 유닉스 기반 시스템은, 프로그램을 실행하기 전에 해당 파일에 “executable(실행)” 표시를 해줘야 하기 때문입니다. 실행 표시를 하기 위해서는, 터미널 앱을 열고 django-admin.py가 설치되어 있는 디렉토리로 이동합니다. (cd 명령을 사용) 그리고 sudo chmod +x django-admin.py 명령어를 실행합니다.

Note

여러분은 파이썬이나 Django 구성요소에 내장된 이름을 프로젝트 이름을 정하는 것을 피해야 합니다. 특히, django (Django 자체와 충돌 발생)나 test(파이썬 패키지에 내장되어 있어 충돌이 발생)과 같은 이름 사용을 주의해야 한다는 것입니다.

django-admin.py는 여러분이 Django를 python setup.py 명령으로 설치를 하였다면 여러분의 시스템 경로에 존재할 것입니다. 만약 찾을 수 없다면 여러분은 site-packages/django/bin 여기에서 찾을 수 있을 것입니다. (site-packages는 파이썬의 설치 경로 안에 있습니다.) 불편하다면 django-admin.py/usr/local/bin로 심볼릭 링크를 걸어두는 것을 고려해 볼 수 있습니다.

어디에서 이 코드가 실행 되나요?

만약 여러분이 PHP 개발자라면, 아마도 웹 서버의 document root 디렉토리(/var/www과 같은 장소)에 코드를 Django와 같이 올리려할 것 입니다. 장고에서는 그렇게 하지 않습니다. 파이썬 코드를 웹 서버와 같이 올려둘 경우 사람들이 웹을 통해 코드를 볼 수 있을 가능성이 있어 위험합니다. 이는 보안상 좋지 않습니다.

여러분의 코드를 document root 밖의 폴더, 예를 들어 /home/mycode 와 같은 폴더에 넣어 두는 것이 좋습니다.

startproject를 이용해서 만들어진 구조를 확인해 봅시다.

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

여러분이 보시는 것과 다른가요?

최근에 기본적인 프로젝트 레이아웃이 변경이 되었습니다. 만약 (내부에 mysite/ 디렉토리가 없는) “수평적인” 레이아웃이 보인다면, 여러분이 이 튜토리얼과 다른 버전의 Django를 사용하고 있는 것입니다. 이럴 경우 여러분은 예전 튜토리얼로 공부를 하는 방법과, 새로운 Django 버전을 설치하는 방법을 선택할 수 있습니다.

이러한 파일은:

  • 밖에 있는 mysite/ 디렉토리는 여러분의 프로젝트의 컨테이너 역할을 하는 디렉토리입니다. 이 이름은 Django에서 별로 중요하지 않으므로, 원한다면 어떠한 이름으로도 변경할 수 있습니다.
  • manage.py: 명령 유틸리티를 이용하여 여러분은 다양한 방법으로 Django 프로젝트와 상호작용을 할 수 있습니다. 여러분은 django-admin.py and manage.py에서 manage.py에 관한 더 많은 정보를 얻을 수 있습니다.
  • 안쪽 mysite/ 디렉토리는 여러분이 만든 실제 파이썬 패키지입니다. 이 패키지 이름은 여러분이 코드 안에서 import 할 때 사용할 수 있습니다(e.g. import mysite.settings).
  • mysite/__init__.py: 아무 것도 없는 빈 파일인 이 파일은 파이썬에서 이 디렉토리가 파이썬 패키지라는 것을 알려줍니다. (만약 여러분이 파이썬을 처음 공부하시는 분이라면 more about packages에서 공식문서를 읽어 보시기 바랍니다.)
  • mysite/settings.py: Django에서 필요한 설정 및 구성을 하는 파일입니다. Django settings 문서에서 여러분의 Django 설정을 어떻게 해야 하는지 알려줄 것입니다.
  • mysite/urls.py: Django 프로젝트에서 URL을 설정합니다; Django site의 “목차(사이트 맵)”입니다. 여러분들은 URL dispatcher에서 URL에 관한 더 많은 정보를 읽어 볼 수 있습니다.
  • mysite/wsgi.py: 여러분의 프로젝트가 WSGI 호환 서버에서 서비스를 하기 위한 진입점입니다. 자세한 사항은 How to deploy with WSGI에서 확인하세요.

개발 서버

동작하는지 확인해 봅시다. 만약 여러분의 현재 위치가 바깥쪽의 mysite 디렉토리가 아닐 경우 그 위치로 이동합니다. 그리고 python manage.py runserver 명령어를 실행합니다. 이제 여러분은 명령행에서 다음과 같이 출력되는 것을 볼 수 있을 것입니다.

Validating models...
0 errors found.

Django version 1.4, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

이제 여러분은 Django 개발 서버를 시작했습니다. 이것은 경량 웹 서버로서 순수하게 파이썬으로 제작되었습니다. 여러분이 Apache와 같은 프로덕션 서버를 구축하지 않고도 서버가 준비되기 전까지 뭔가를 빨리 개발할 수 있도록 Django에 포함되어 있습니다.

중요사항: 절대 서비스 서버 환경으로 사용하지 마십시오. 이 서버는 오직 개발하는 동안만 사용하도록 계획된 것입니다. (우리의 목적은 웹 프레임워크를 만드는 것이지 웹 서버를 만드는 것이 아닙니다.)

서버 동작을 확인하기 위해서 웹 브라우저에서 http://127.0.0.1:8000/를 방문해 보세요. 예쁜 라이트 블루 파스텔 톤의 “Welcome to Django” 페이지를 볼 수 있을 것입니다. 성공!

포트 변경하기

기본적으로, runserver 명령어로 개발 서버를 시작할 경우 내부 IP에 8000번 포트를 사용합니다.

여러분이 서버의 포트를 변경하기를 원한다면, 명령행에 인자를 사용할 수 있습니다. 예를 들어 다음 명령어는 8080 포트로 변경합니다.

python manage.py runserver 8080

여러분이 서버 IP도 변경하길 원한다면 포트와 함께 전달하면 됩니다. 그렇게 하면 모든 공용 IP에서 수신을 대기할 수 있습니다.(여러분이 다른 컴퓨터에서 여러분의 사이트를 보여주길 원한다면 유용합니다) 사용법은 다음과 같습니다.

python manage.py runserver 0.0.0.0:8000

개발 서버에 관해서는 runserver에서 찾으실 수 있습니다.

데이터베이스 설치

이제, mysite/settings.py 파일을 수정해 봅시다. 이 파일은 Django 설정을 하는 모듈 수준의 변수를 가진 파이썬의 표준 모듈입니다. 여러분의 데이터베이스와 맞도록 DATABASES 'default' 키를 수정하세요.

  • ENGINE'django.db.backends.postgresql_psycopg2', 'django.db.backends.mysql', 'django.db.backends.sqlite3' 또는 'django.db.backends.oracle' 중 선택하세요. 다른 백엔드들도 준비되어 있습니다.

  • NAME – 여러분의 데이터베이스 이름입니다. 만약 여러분이 SQLite를 사용한다면, 데이터베이스가 여러분의 컴퓨터에 있는 파일이 될 것입니다; 그 경우, NAME의 값으로 파일명을 포함하는 절대경로를 지정합니다. 만약 파일이 존재하지 않는다면, 여러분이 데이터베이스를 최초로 동기화할 때에 자동으로 만들어질 것입니다.(아래에 설명합니다)

    경로를 지정할 때에는 항상 정방향의 슬래쉬(/)를 사용해야 하며, 이는 Windows에서도 마찬가지입니다(예: C:/homes/user/mysite/sqlite3.db).

  • USER – 데이터베이스 사용자명(SQLite에서는 사용하지 않습니다).

  • PASSWORD – 데이터베이스 암호(SQLite에서는 사용하지 않습니다).

  • HOST – 데이터베이스가 있는 호스트 데이터베이스가 동일한 물리적 장치에 있다면 비어있는 문자열을 사용합니다. (SQLite에서는 사용하지 않습니다).

만약 여러분이 새로운 데이터베이스를 사용하길 원하신다면, 쉽게 사용 가능한 SQLite를 추천합니다. ENGINE'django.db.backends.sqlite3'를 입력하고 NAME에 데이터베이스 파일이 저장될 경로를 입력하시면 됩니다. SQLite는 파이썬 2.5 이상부터 포함되어 있으므로 여러분은 데이터베이스 지원을 위해서 아무 것도 설치할 필요가 없습니다.

Note

여러분이 PostgreSQL나 MySQL을 사용한다면, 데이터베이스가 만들어져 있는지 확인해야 합니다. 만일 데이터베이스가 생성되어 있지 않다면 데이터베이스에 접속 가능한 프롬프트에서 “CREATE DATABASE database_name;“명령어를 이용하여 데이터베이스를 만들 수 있습니다.

여러분이 SQLite을 사용한다면, 여러분은 아무 것도 만들 필요가 없습니다 - 데이터베이스 파일이 필요할 때 자동으로 생성됩니다.

여러분이 settings.py을 수정할 때, TIME_ZONE을 여러분의 시간대에 맞게 수정하세요. 기본값은 미국 중부(시카고) 시간입니다.

또한, 파일 제일 아래쪽에 있는 INSTALLED_APPS을 확인하세요. 여기에는 Django 인스턴스에서 사용하는 모든 애플리케이션의 이름을 갖고 있습니다. 앱은 여러 프로젝트에서 사용할 수 있고, 여러분은 다른 프로젝트에서 사용 가능하도록 패키징하여 재배포할 수 있습니다.

기본적으로, INSTALLED_APPS Django 프로젝트 생성시 다음과 같은 앱을 포함하고 있습니다.

이 애플리케이션들은 기본적으로 Django 사용에 있어 일반적인 케이스에 대한 편의를 제공하기 위해 포함되어 있습니다.

각각의 애플리케이션은 적어도 하나의 데이터베이스 테이블을 사용하기 때문에, 우리는 데이터베이스 테이블이 사용되기 전에 테이블을 만들어야 합니다. 그렇게 하려면 다음 명령어를 실행하세요.

python manage.py syncdb

syncdb 명령어는 settings.py 파일에 있는 데이터베이스 설정에 따라 INSTALLED_APPS에서 설정되어 있는 앱을 확인하고 필요한 데이터베이스 테이블을 만듭니다. 여러분들은 각 데이터베이스 테이블이 생성되는 메시지를 볼 수 있고, 인증 시스템에서 여러분에게 관리자 계정 정보를 입력하는 명령 프롬프트를 보여 줄 것입니다. 여기에서 관리자 계정 정보를 만들면 됩니다.

만약 Django에서 생성한 데이터베이스의 테이블 목록을 보고 싶다면, 해당 데이터베이스에 접속할 수 있는 클라이언트에서 다음 명령어 중 해당 데이터베이스에 맞는 명령어를 입력하세요.(\dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite)).

미니멀리스트를 위한 팁

위에서 말했듯이, 기본 애플리케이션에는 일반적인 경우에 필요한 것들이 포함되어 있지만, 그것들이 모두 필요하지 않을 수도 있습니다. 만약 그중 일부 또는 전부가 불필요하다면, syncdb를 실행하기 전에 INSTALLED_APPS에서 주석 처리를 하거나 삭제하셔도 무방합니다. syncdb 명령을 실행하면 INSTALLED_APPS 안에 설정된 앱에 대해서만 테이블을 생성합니다.

모델 만들기

이제 프로젝트를 위한 환경 설정을 완료하였습니다. 이제 작업을 시작할 수 있습니다.

여러분이 작성한 각 애플리케이션은 Django에서 파이썬 패키지로 구성되어 특정 규칙에 따라, Python path 어딘가에 존재합니다. Django는 자동으로 기본적인 디렉토리 구조를 생성하는 유틸리티를 포함하고 있어서, 여러분은 디렉토리 구조를 생성하는 것보다 코드를 작성하는 것에 초점을 맞출 수 있게 해줍니다.

프로젝트 vs. 앱

프로젝트와 앱은 무엇이 다를까요? 앱은 어떤 기능을 하는 웹 애플리케이션으로, 웹로그 시스템, 공공 기록의 데이터베이스 또는 간단한 투표 앱과 같은 것입니다. 프로젝트는 특정 웹사이트에 대한 구성 및 앱들의 집합입니다. 프로젝트는 다양한 앱을 포함하고 있습니다. 앱은 다양한 프로젝트에서 사용할 수 있습니다.

여러분의 앱은 Python path 어딘가에 있습니다. 이 튜토리얼에서 우리는 manage.py을 이용하여 투표 앱을 만들 것입니다. 이것은 mysite의 서브모듈보다도 더 중요한 모듈입니다.

여러분이 앱을 만들기 위해서는 manage.py와 같은 디렉토리에서 다음과 같은 명령어를 입력합니다.

python manage.py startapp polls

이 명령어는 다음과 같은 구조를 갖는 polls 디렉토리를 만들 것입니다.

polls/
    __init__.py
    models.py
    tests.py
    views.py

이 디렉토리 구조는 투표 애플리케이션을 수용할 수 있습니다.

Django에서 데이터베이스 웹 앱 작성의 첫 단계는 데이터베이스 모델을 정의하는 것입니다. – 본질적으로 추가적인 메타데이터와 데이터베이스 레이아웃을 정의하는 작업입니다.

철학

모델은 여러분의 데이터에 대한 최종적인 소스입니다. 이것은 여러분의 데이터에 대한 기본적인 필드와 행동이 포함되어 있습니다. Django는 DRY 원칙을 따릅니다. 이것의 목표는 여러분의 모델을 한 곳에서 정의하고 자동으로 결과를 생성해내는 것입니다.

우리의 간단한 투표 앱에서는 두 개의 모델, 설문(Poll)과 선택(Choice)을 구현할 것입니다. poll은 ‘질문’과 ‘발행일’ 필드를 갖고 있습니다. choice는 두개의 필드를 갖고 있습니다: ‘선택지’와 ‘투표 집계’ 각 선택은 poll과 관련이 있습니다.

이것의 개념은 간단한 파이썬 클래스로 표현이 됩니다. polls/models.py을 다음과 같이 수정하세요.

from django.db import models

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

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length=200)
    votes = models.IntegerField()

코드는 간단합니다. 각 모델은 django.db.models.Model의 서브클래스로 표현됩니다. 각 모델은 몇개의 클래스 변수를 갖고 있고, 이것은 각각 데이터베이스 필드로 표현됩니다.

각 필드는 Field 클래스의 인스턴스로 표현됩니다. – e.g., CharField는 character 필드 그리고 DateTimeField은 datetime 필드. 이것은 Django에게 데이터의 필드가 어떤 타입인지 알려줍니다.

Field 인스턴스의 이름은(e.g. question 또는 pub_date) 기계친화적인 필드 이름입니다. 여러분은 이것을 여러분의 파이썬 코드에서 사용하고, 데이터베이스는 필드 이름으로 사용합니다.

여기에서 여러분은 선택적으로 Field의 첫 번째 인자를 사람이 읽을 수 있는 이름으로 지정할 수 있습니다. 그것은 Django의 내부적으로 사용되고, 두 가지로 설명해 줍니다. 만약 이 필드를 제공하지 않는다면, Django는 기계가 읽을 수 있는 이름만을 사용해야 합니다. 예제에서, 우리는 Poll.pub_date에 대해서만 사람이 읽을 수 있는 이름을 정의했습니다. 이 모델에서는 다른 모든 필드는 기계가 읽을 수 있는 이름도 충분히 사람이 읽을 수 있는 이름이기 때문입니다.

일부 Field 클래스들은 필수 요소를 필요로 합니다. 예를 들어 CharField에는 max_length가 필요합니다. 이것은 데이터베이스 스키마에서만 사용하는 것이 아니라 데이터 검증에서도 사용 합니다. 우리는 그것을 곧 보게 될 것입니다.

마지막으로, ForeignKey를 이용하여 릴레이션십을 정의했습니다. 이것은 Choice가 하나의 Poll과 관계가 있다고 Django에게 알려줍니다. Django는 다 대 일, 다 대 다, 일 대 일 등의 공통적인 데이터베이스 릴레이션십을 제공합니다.

모델 활성화하기

이 작은 모델 코드는 Django에게 많은 정보를 전달합니다. 이것을 통해 Django는 다음과 같은 것을 할 수 있습니다.

  • 이 앱에서 필요로 하는 데이터베이스 스키마 생성 (CREATE TABLE 문).
  • Poll과 Choice 개체에 접근하기 위한 데이터베이스 액세스 API 생성.

그 전에 우리는 우리의 프로젝트에게 polls 앱이 설치되었다고 알려줘야 합니다.

철학

Django앱은 “플러그”입니다. 여러분은 여러 프로젝트에서 앱을 사용할 수 있으며, 앱을 재배포할 수 있습니다. 왜냐하면 앱들은 Django 설치와 밀접하게 묶일 필요가 없기 때문입니다.

settings.py 파일에서 INSTALLED_APPS'polls'을 포함하도록 수정합니다. 그러면 다음과 같이 보일 것입니다.

INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    # 'django.contrib.admin',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
    'polls',
)

이제 Django는 polls 앱이 포함되었다는 것을 알게 됩니다. 다음 명령어를 실행해 봅시다.

python manage.py sql polls

여러분은 다음과 비슷한 내용을 보실 수 있습니다.(투표 앱 CREATE TABLE SQL문)

BEGIN;
CREATE TABLE "polls_poll" (
    "id" serial NOT NULL PRIMARY KEY,
    "question" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id") DEFERRABLE INITIALLY DEFERRED,
    "choice" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
COMMIT;

다음을 참고하세요.

  • 정확한 출력은 사용 중인 데이터베이스에 따라 달라집니다.
  • 테이블 이름은 앱 이름(polls)과 소문자 모델 이름 –poll, choice과 합성되어 자동으로 생성됩니다.(여러분은 이 동작을 재정의할 수 있습니다.)
  • 기본 키(ID)는 자동으로 추가됩니다. (이것도 재정의할 수 있습니다.)
  • 관례상, Django는 외래 키의 필드 이름에 "_id"를 추가합니다.(물론, 이것 또한 재정의 가능합니다.)
  • 외래 키 릴레이션십은 REFERENCES 문으로 명시됩니다.
  • 그것은 사용중인 데이터베이스에 맞게 auto_increment (MySQL), serial (PostgreSQL), integer primary key (SQLite) 등과 같이 필드 유형에 맞게 자동으로 사용됩니다. 같은 필드 이름의 인용을 위해 사용된다. – e.g., 큰따옴표 또는 작은 따옴표. 이 튜토리얼의 저자는 PostgreSQL을 이용하여 실행하였으므로, 예제의 출력물 역시 PostgreSQL 문법을 따릅니다.
  • sql 명령어는 실제로 여러분의 데이터 베이스에 SQL문을 실행하지 않습니다. 이것 단지 화면에 출력해 주는 것입니다. 이것은 여러분은 SQL Django가 어떻게 생각하는지 알기 위해 필요합니다. 원한다면 이것을 복사하여 여러분의 데이터베이스 프롬프트에서 사용할 수 있습니다. 그러나, 우리는 SQL을 Django에 맡겨버리는 쉬운 방법을 곧 보게 될 것입니다.

만약 여러분이 이것에 관심이 있다면 다음 명령어를 실행하세요.

이러한 명령에 의해 출력된 내용을 살펴보면 여러분은 실제로 발생할 내용에 대해 이해할 수 있을 것입니다.

이제, syncdb 를 다시 실행하여 여러분의 데이터베이스에 모델 테이블을 만드세요.

python manage.py syncdb

syncdb 명령은 INSTALLED_APPS 있는 앱 중 이미 데이터베이스에 존재하는 앱을 제외한 모든 앱에 대하여 sqlall를 실행합니다. 이것은 여러분이 syncdb 명령을 마지막으로 실행한 이후에 일어난 모든 앱에 대한 테이블과 초기 데이터, 인덱스를 만듭니다. syncdb는 원할 때마다 호출이 가능하며, 이것은 오직 생성되지 않은 테이블에 대해서만 테이블을 생성합니다.

manage.py 유틸리티가 무엇을 할 수 있는지에 대한 정보는 django-admin.py 문서를 읽어 보십시오.

API와 놀기

이제, 대화식 파이썬 쉘을 이용하여 Django API를 갖고 놀 수 있습니다. 파이썬 쉘을 호출하려면 다음 명령어를 입력하세요.

python manage.py shell

단순히 “python”이라고 입력하지 않고 위와 같이 하는 이유는, manage.py 파일이 settings.py에서 Django에게 파이썬 가져오기 경로를 DJANGO_SETTINGS_MODULE 환경변수를 통해 제공하기 때문입니다.

manage.py 건너뛰기

만약 manage.py를 사용하지 않는다 해도 문제 없습니다. 단지 mysite.settingsDJANGO_SETTINGS_MODULE 환경변수를 설정하고 manage.py 파일이 있는 같은 디렉토리에서 python을 실행하면 됩니다. (또는 그 디렉토리가 파이썬 경로에 위치하거나 import mysite 해야 사용할 수 있습니다).

더 많은 정보를 원한다면 django-admin.py 문서를 확인하세요.

일단 쉘에서 데이터베이스 API를 확인해 보세요.

>>> from polls.models import Poll, Choice   # 방금 작성한 모델 클래스들을 임포트.

# 아직 설문이 존재하지 않음.
>>> Poll.objects.all()
[]

# 새로운 Poll을 생성.
# 기본 설정에서 타임 존에 대한 지원이 활성화되어 있으므로,
# Django는 pub_date에 대하여 tzinfo의 datetime을 예상합니다.
# datetime.datetime.now() 대신에 timezone.now()를 사용하는 것이 올바르게 처리됩니다.
>>> from django.utils import timezone
>>> p = Poll(question="What's new?", pub_date=timezone.now())

# 개체를 데이터베이스에 저장. save()를 명시적으로 호출하여야 합니다.
>>> p.save()

# 이제 ID를 갖게 되었습니다. 사용하는 데이터베이스에 따라서, ID가 "1"이 아니라
# "1L"이 될 수 있음에 유의하시기 바랍니다. 별로 중요한 것은 아니고, 그저 여러분이
# 사용하는 데이터베이스 백엔드가 정수를 파이썬의 long integer 개체로 반환함을
# 의미합니다.
>>> p.id
1

# 파이썬 속성을 통하여 데이터베이스 컬럼에 접근.
>>> p.question
"What's new?"
>>> p.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# 속성을 변경함으로써 값을 변경하고, save()를 호출.
>>> p.question = "What's up?"
>>> p.save()

# objects.all()을 하면 데이터베이스의 모든 설문을 볼 수 있습니다.
>>> Poll.objects.all()
[<Poll: Poll object>]

잠시만요. <Poll: Poll object>는 이 개체 자체를 표현하는 것이지 개체의 내용을 표현하지는 않습니다. 우리는 polls 모델을 수정하여(polls/models.py 파일) PollChoice__unicode__()를 추가하여 원하는 내용을 표현할 수 있습니다.

class Poll(models.Model):
    # ...
    def __unicode__(self):
        return self.question

class Choice(models.Model):
    # ...
    def __unicode__(self):
        return self.choice

__unicode__() 메소드를 추가하는 것은 여러분의 모델에서 매우 중요합니다. 이것은 대화식 프롬프트에서 사용할 때 뿐만 아니라, Django에서 자동 생성되는 관리자 화면에서 표현할 때도 사용됩니다.

__unicode__()는 되고 __str__()은 안되나요?

만약 여러분이 파이썬에 익숙한 경우, 여러분은 __unicode__() 메소드 대신 __str__()를 추가하는 습관이 있을 수 있습니다. 우리가 __unicode__()을 사용하는 이유는 Django 모델에서는 기본적으로 유니코드를 사용하기로 약속했기 때문입니다. 데이터가 반환될 때 여러분의 데이터베이스에 있는 모든 데이터는 유니코드로 변환되어 반환됩니다.

Django 모델은 기본적으로 __str__() 메소드는 __unicode__()를 호출한 결과를 UTF-8 바이트 스트링으로 변환하여 보여줍니다. 이 말은 unicode(p)는 유니코드 문자열을, str(p)은 UTF-8로 변환된 기본 문자열을 반환한다는 뜻입니다.

이 모든 것이 혼란스럽다면 모델에서 __unicode__() 메소드만 사용한다는 것을 기억하세요. 운이 좋다면, 이 모든 것은 잘 동작할 것입니다.

참고로 이것들은 일반적인 파이썬 메소드입니다. 맞춤 메소드를 추가하는 방법을 살펴보도록 합시다.

import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

참고로 추가한 import datetimefrom django.utils import timezone은 각각 파이썬의 표준 메소드인 datetime과 Django의 time-zone-related 유틸리티에 들어 있는 django.utils.timezone을 참조하세요. 파이썬에서의 시간 처리에 대해 익숙하지 않다면, 타임 존 지원 문서에서 배울 수 있습니다.

저장 후 python manage.py shell 이용하여 새로운 파이썬 대화형 쉘을 실행하세요.

>>> from polls.models import Poll, Choice

# __unicode__()를 추가한 것이 동작하는지 확인.
>>> Poll.objects.all()
[<Poll: What's up?>]

# Django는 키워드 인자만으로 구동되는 두터운 데이터베이스 조회 API를 제공합니다.
>>> Poll.objects.filter(id=1)
[<Poll: What's up?>]
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]

# 2012년의 설문을 조회.
>>> Poll.objects.get(pub_date__year=2012)
<Poll: What's up?>

>>> Poll.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Poll matching query does not exist.

# 기본 키를 통해 조회하는 것은 매우 빈번하므로, Django는 기본 키 추출 조회에 대한
# 지름길을 제공합니다.
# 다음은 Poll.objects.get(id=1)과 동일합니다.
>>> Poll.objects.get(pk=1)
<Poll: What's up?>

# 우리의 맞춤 메소드가 동작하는지 확인.
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True

# 설문에 두 가지 선택사항을 주도록 하겠습니다. create를 호출하여 새로운 choice를 만들고,
# INSERT 문을 수행하여, 기존의 가능한 choice의 집합에 추가하여 새로운 Choice 개체를 반환합니다.
# Django는 "다른 편"의 ForeignKey 릴레이션(예: poll의 choice)을 생성하며
# 이는 API를 통하여 접근할 수 있습니다.
>>> p = Poll.objects.get(pk=1)

# 관련된 개체 집합으로부터 choice를 표시하는데, 아직까지는 존재하지 않습니다.
>>> p.choice_set.all()
[]

# 세 가지 choice를 생성.
>>> p.choice_set.create(choice='Not much', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice='The sky', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice='Just hacking again', votes=0)

# Choice 개체는 API를 통해 관련된 Poll 개체에 접근할 수 있습니다.
>>> c.poll
<Poll: What's up?>

# 그 역도 성립합니다. Poll 개체도 Choice 개체에 접근할 수 있습니다.
>>> p.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3

# API는 여러분이 필요로 하는 릴레이션십을 자동적으로 따라갑니다.
# 릴레이션을 분리하려면 두 개의 밑줄을 사용합니다.
# 이는 여러분이 원하는 단계만큼 사용할 수 있으며 제한이 없습니다.
# pub_date가 2012인 poll에 대한 모든 Choice를 찾습니다.
>>> Choice.objects.filter(poll__pub_date__year=2012)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]

# choice 중 하나를 삭제해봅시다. delete()를 사용하면 됩니다.
>>> c = p.choice_set.filter(choice__startswith='Just hacking')
>>> c.delete()

모델 릴레이션에 대한 자세한 사항은 관계된 개체에 접근하기를 참조하세요. API에서 이중 밑줄(__)을 어떻게 사용하는지에 대한 자세한 사항은 필드 조회에서 확인하세요. 데이터베이스 API에 대한 자세한 사항은 데이터베이스 API 레퍼런스에서 확인하세요.

이제 여러분이 API를 익숙하게 사용하신다면, 튜토리얼 2부로 가서 Django에서 자동으로 생성되는 관리자에 대하여 확인하세요.