{"title":"첫 번째 장고 앱 작성하기, part 2","version":"1.11","locale":"ko","docname":"intro/tutorial02","url":"/ko/1.11/intro/tutorial02/","canonical":"https://djangodocs.dev/ko/1.11/intro/tutorial02/","summary":"이 튜토리얼은 튜토리얼 1장 이후부터 이어집니다. 데이터베이스를 설치하고 첫 모델을 생성한 후, Django 에서 자동 생성되는 관리용 사이트에 대한 짧은 소개를…","html":"<h1>첫 번째 장고 앱 작성하기, part 2<a class=\"heading-anchor\" href=\"#writing-your-first-django-app-part-2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>이 튜토리얼은 <a class=\"reference internal\" href=\"/ko/1.11/intro/tutorial01/\"><span class=\"doc\">튜토리얼 1장</span></a> 이후부터 이어집니다. 데이터베이스를 설치하고 첫 모델을 생성한 후, Django 에서 자동 생성되는 관리용 사이트에 대한 짧은 소개를 하겠습니다.</p>\n<section id=\"database-setup\">\n<h2>데이터베이스 설치<a class=\"heading-anchor\" href=\"#database-setup\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>이제, <code class=\"file docutils literal notranslate\">mysite/settings.py</code> 파일을 열어보세요. 이 파일은 Django 설정을 모듈 변수로 표현한 보통의 Python 모듈 입니다.</p>\n<p>기본적으로는 SQLite 을 사용하도록 구성되어 있습니다. 만약 데이터베이스를 처음 경험해보거나, Django 에서 데이터베이스를 한번 경험해 보고 싶다면, SQLite 가 가장 간단한 방법입니다. SQLite 는 Python 에서 기본으로 제공되기 때문에 별도로 설치할 필요가 없습니다. 그러나 실제 project 를 시작할 때에는, 나중에 데이터베이스를 교체하느라 골치아파질 일을 피하기 위해서라도 PostgreSQL 같이 좀 더 확장성있는 데이터베이스를 사용하고 싶을 겁니다.</p>\n<p>다른 데이터베이스를 사용해보고 싶으시다면, 적절한 <a class=\"reference internal\" href=\"/ko/1.11/topics/install/#database-installation\"><span class=\"std std-ref\">데이터베이스 연결</span></a> 을 설치하고, 데이터베이스 연결 설정과 맞게끔 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a> <code class=\"docutils literal notranslate\">'default'</code> 항목의 값을 다음의 키 값으로 바꿔주세요.</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-DATABASE-ENGINE\"><code class=\"xref std std-setting docutils literal notranslate\">ENGINE</code></a> – <code class=\"docutils literal notranslate\">'django.db.backends.sqlite3'</code>, <code class=\"docutils literal notranslate\">'django.db.backends.postgresql'</code>, <code class=\"docutils literal notranslate\">'django.db.backends.mysql'</code>, or <code class=\"docutils literal notranslate\">'django.db.backends.oracle'</code>. 그 외에 <a class=\"reference internal\" href=\"/ko/1.11/ref/databases/#third-party-notes\"><span class=\"std std-ref\">서드파티 백엔드</span></a> 를 참조.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-NAME\"><code class=\"xref std std-setting docutils literal notranslate\">NAME</code></a> – 데이터베이스의 이름. 만약 SQLite 를 사용 중이라면, 데이터베이스는 당신의 컴퓨터의 파일로서 저장됩니다. 이 경우, <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-NAME\"><code class=\"xref std std-setting docutils literal notranslate\">NAME</code></a> 는 파일명을 포함한 절대 경로 로서 지정되어야 합니다.기본 값은 <code class=\"docutils literal notranslate\">os.path.join(BASE_DIR, 'db.sqlite3')</code> 로 정의되어 있으며, project 디렉토리 내에 <code class=\"docutils literal notranslate\">db.sqlite3</code> 파일로 저장됩니다.</p></li>\n</ul>\n<p>SQLite 를 데이터베이스로 사용하지 않는 경우, <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-USER\"><code class=\"xref std std-setting docutils literal notranslate\">USER</code></a>, <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-PASSWORD\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD</code></a>, <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a> 같은 추가 설정이 반드시 필요합니다. 더 자세한 내용은 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a> 문서를 참조해 주세요.</p>\n<aside class=\"admonition-for-databases-other-than-sqlite admonition\" role=\"note\">\n<p class=\"admonition-title\">SQLite가 아닌 데이터베이스라면</p>\n<p>만약 SQLite 이외의 데이터베이스를 사용하는 경우, 이 시점에서 데이터베이스를 생성해야 합니다. 데이터베이스의 대화형 프롬프트 내에서 “<code class=\"docutils literal notranslate\">CREATE DATABASE database_name;</code>” 명령을 실행하면 됩니다.</p>\n<p>또한, <code class=\"file docutils literal notranslate\">mysite/settings.py</code> 에 설정된 데이터베이스 사용자가 “create database” 권한이 있는지도 확인해 봐야 합니다. 튜토리얼을 진행하며 필요한 경우 <a class=\"reference internal\" href=\"/ko/1.11/topics/testing/overview/#the-test-database\"><span class=\"std std-ref\">테스트 데이터베이스</span></a> 를 자동으로 생성할 수 있도록 해줍니다.</p>\n<p>SQLite 를 사용하고 계시다면, 아무것도 미리 생성할 필요가 없습니다. 데이터베이스 파일은 필요할때마다 자동으로 생성될 것입니다.</p>\n</aside>\n<p><code class=\"file docutils literal notranslate\">mysite/settings.py</code> 을 편집하는 동안, 당신의 시간대에 맞춰 set <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-TIME_ZONE\"><code class=\"xref std std-setting docutils literal notranslate\">TIME_ZONE</code></a> 값을 설정하기 바랍니다.</p>\n<p>또한, 이 파일의 윗쪽에 있는 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 에 대해 언급하자면, 이 파일은 현재 Django 인스턴스에서 활성화된 모든 Django 어플리케이션들의 이름이 담겨 있습니다. App 들은 다수의 project 에서 사용될 수 있고, 다른 project 에서 쉽게 사용 될 수 있도록 패키지 하여 배포할 수 있습니다.</p>\n<p>기본적으로는, <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 는 Django 와 함께 딸려오는 다음의 app 들을 포함합니다.</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/contrib/admin/#module-django.contrib.admin\" title=\"django.contrib.admin: Django's admin site.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.admin</code></a> – 관리용 사이트, 곧 사용하게 될겁니다.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/topics/auth/#module-django.contrib.auth\" title=\"django.contrib.auth: Django's authentication framework.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.auth</code></a> – 인증 시스템.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/contrib/contenttypes/#module-django.contrib.contenttypes\" title=\"django.contrib.contenttypes: Provides generic interface to installed models.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.contenttypes</code></a> – 컨텐츠 타입을 위한 프레임워크.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/topics/http/sessions/#module-django.contrib.sessions\" title=\"django.contrib.sessions: Provides session management for Django projects.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.sessions</code></a> – 세션 프레임워크.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/contrib/messages/#module-django.contrib.messages\" title=\"django.contrib.messages: Provides cookie- and session-based temporary message storage.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.messages</code></a> – 메세징 프레임워크.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/contrib/staticfiles/#module-django.contrib.staticfiles\" title=\"django.contrib.staticfiles: An app for handling static files.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.staticfiles</code></a> – 정적 파일을 관리하는 프레임워크.</p></li>\n</ul>\n<p>이 어플리케이션들은 일반적인 경우에 사용하기 편리하도록 기본으로 제공됩니다.</p>\n<p>이러한 기본 어플리케이션들 중 몇몇은 최소한 하나 이상의 데이터베이스 테이블을 사용하는데, 그러기 위해서는 데이터베이스에서 테이블을 미리 만들 필요가 있습니다. 이를 위해, 다음의 명령을 실행해봅시다.</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py migrate\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> 명령은 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 의 설정을 탐색하여, <code class=\"file docutils literal notranslate\">mysite/settings.py</code> 의 데이터베이스 설정과 app 과 함께 제공되는 데이터베이스 migrations(나중에 설명하겠습니다) 에 따라, 필요한 데이터베이스 테이블을 생성합니다. 이 명령을 수행하면 각 migration 이 적용되는 메세지가 화면에 출력되는 것을 확인할 수 있습니다. 어떤 내용이 생성되었는지 궁금하다면, 데이터베이스 클라이언트로 접속한 후, <code class=\"docutils literal notranslate\">\\dt</code> (PostgreSQL), <code class=\"docutils literal notranslate\">SHOW TABLES;</code> (MySQL), <code class=\"docutils literal notranslate\">.schema</code> (SQLite), <code class=\"docutils literal notranslate\">SELECT TABLE_NAME FROM USER_TABLES;</code> (Oracle) 을 통해 Django 가 생성한 테이블을 확인해 볼 수 있습니다.</p>\n<aside class=\"admonition-for-the-minimalists admonition\" role=\"note\">\n<p class=\"admonition-title\">최소주의자(minimalists)들을 위하여</p>\n<p>위에서 언급했다시피, 기본으로 제공되는 어플리케이션은 일반적인 상황을 염두에 두었으나, 모두에게 필요한것은 아닙니다. 만약 이것들이 필요 없다고 생각되시면, <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> 를 실행하기 전에 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 에서 제거할 어플리케이션들을 그냥 주석처리(comment-out) 하시거나 삭제하시면 됩니다. <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> 명령은 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 에 등록된 어플리케이션에 한하여 실행될 것입니다.</p>\n</aside>\n</section>\n<section id=\"creating-models\">\n<span id=\"id1\"></span><h2>모델 만들기<a class=\"heading-anchor\" href=\"#creating-models\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>이제, 모델을 정의해 보겠습니다. 본질적으로, 모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조(layout)를 말합니다.</p>\n<aside class=\"admonition-philosophy admonition\" role=\"note\">\n<p class=\"admonition-title\">철학</p>\n<p>모델(“model”)은 데이터에 관한 단 하나의, 가장 확실한 진리의 원천입니다. 이것은 당신이 저장하는 데이터의 필수적인 필드들과 동작들을 포함하고 있습니다. Django 는 <a class=\"reference internal\" href=\"/ko/1.11/misc/design-philosophies/#dry\"><span class=\"std std-ref\">DRY 원칙</span></a> 을 따릅니다. 이 원칙에 따라 데이터 모델을 한곳에서 정의하고, 이것으로부터 자동으로 뭔가를 유도하는 것이 목표입니다.</p>\n<p>이 규칙은 migration 에도 해당됩니다. Ruby On Rails 와는 다르게, Django 의 경우 migration 들은 모두 모델 파일로 부터 유도되며, 이 migration 들은 Django 가 데이터 스키마의 업데이트를 통해 현재의 모델에 도달할 수 있게 해주는, 일종의 역사와 같습니다.</p>\n</aside>\n<p>우리가 만드는 단순한 설문조사(poll) 앱을 위해 <code class=\"docutils literal notranslate\">Question</code> 과 <code class=\"docutils literal notranslate\">Choice</code> 라는 두개의 모델을 만들어 보겠습니다. <code class=\"docutils literal notranslate\">Question</code> 은 질문(question) 과 발행일(publication date) 을 위한 두개의 필드를 가집니다. <code class=\"docutils literal notranslate\">Choice</code> 는 선택지(choice) 와 표(vote) 계산을 위한 두개의 필드를 가집니다. 각 <code class=\"docutils literal notranslate\">Choice</code> 모델은 <code class=\"docutils literal notranslate\">Question</code> 모델과 연관(associated) 됩니다.</p>\n<p>이런 개념은 간단한 Python 클래스로 표현할 수 있습니다. <code class=\"file docutils literal notranslate\">polls/models.py</code> 파일을 수정하여 다음과 같이 만들어 봅시다.</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/models.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/models.py\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Question</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    question_text <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    pub_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateTimeField<span class=\"p\">(</span><span class=\"s1\">&#39;date published&#39;</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Choice</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    question <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Question<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    choice_text <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    votes <span class=\"o\">=</span> models<span class=\"o\">.</span>IntegerField<span class=\"p\">(</span>default<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p>아주 간단한 코드입니다. 각 모델은 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/instances/#django.db.models.Model\" title=\"django.db.models.Model\"><code class=\"xref py py-class docutils literal notranslate\">django.db.models.Model</code></a> 이라는 클래스의 서브클래스로 표현됩니다. 각 모델은 몇개의 클래스 변수를 가지고 있으며, 각각의 클래스 변수들은 모델의 데이터베이스 필드를 나타냅니다.</p>\n<p>데이터베이스의 각 필드는 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> 클래스의 인스턴스로서 표현됩니다. <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> 는 문자(character) 필드를 표현하고, <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a> 는 날짜와 시간(datetime) 필드를 표현합니다. 이것은 각 필드가 어떤 자료형을 가질 수 있는지를 Django 에게 말해줍니다.</p>\n<p>각각의 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> 인스턴스의 이름은 기계가 읽기 좋은 형식(machine-friendly format)의 데이터베이스 필드 이름입니다. 이 필드명을 Python 코드에서 사용할수 있으며, 데이터베이스에서는 컬럼명으로 사용할 것입니다.</p>\n<p><a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> 클래스의 생성자에 선택적인 첫번째 위치 인수를 전달하여 사람이 읽기 좋은(human-readable) 이름을 지정할 수도 있습니다. 이 방법은 Django 의 내부를 설명하는 용도로 종종 사용되는데, 이는 마치 문서가 늘어나는 것 같은 효과를 가집니다. 만약 이 선택적인 첫번째 위치 인수를 사용하지 않으면, Django 는 기계가 읽기 좋은 형식의 이름을 사용합니다. 이 예제에서는, <code class=\"docutils literal notranslate\">Question.pub_date</code> 에 한해서만 인간이 읽기 좋은 형태의 이름을 정의하겠습니다. 그 외의 다른 필드들은, 기계가 읽기 좋은 형태의 이름이라도 사람이 읽기에는 충분합니다.</p>\n<p>몇몇 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> 클래스들은 필수 인수가 필요합니다. 예를 들어, <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a> 의 경우 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.CharField.max_length\" title=\"django.db.models.CharField.max_length\"><code class=\"xref py py-attr docutils literal notranslate\">max_length</code></a> 를 입력해 주어야 합니다. 이것은 데이터베이스 스키마에서만 필요한것이 아닌 값을 검증할때도 쓰이는데, 곧 보게 될것입니다.</p>\n<p>또한 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> 는 다양한 선택적 인수들을 가질 수 있습니다. 이 예제에서는, <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.Field.default\" title=\"django.db.models.Field.default\"><code class=\"xref py py-attr docutils literal notranslate\">default</code></a> 로 하여금 <code class=\"docutils literal notranslate\">votes</code> 의 기본값을 0 으로 설정하였습니다.</p>\n<p>마지막으로, <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\">ForeignKey</code></a> 를 사용한 관계설정에 대해 설명하겠습니다. 이 예제에서는 각각의 <code class=\"docutils literal notranslate\">Choice</code> 가 하나의 <code class=\"docutils literal notranslate\">Question</code> 에 관계된다는 것을 Django 에게 알려줍니다. Django 는 다-대-일(many-to-one), 다-대-다(many-to-many), 일-대-일(one-to-one) 과 같은 모든 일반 데이터베이스의 관계들를 지원합니다.</p>\n</section>\n<section id=\"activating-models\">\n<h2>모델의 활성화<a class=\"heading-anchor\" href=\"#activating-models\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>모델에 대한 이 작은 코드가, Django 에게는 상당한 량의 정보를 전달합니다. 이 정보로 Django 는 다음을 할 수 있습니다.:</p>\n<ul class=\"simple\">\n<li><p>이 app 에 대하여 데이터베이스 스키마 생성 (<code class=\"docutils literal notranslate\">CREATE TABLE</code> statements)</p></li>\n<li><p><code class=\"docutils literal notranslate\">Question</code> 과 <code class=\"docutils literal notranslate\">Choice</code> 객체에 접근하기 위한 Python 데이터베이스 접근 API 를 생성</p></li>\n</ul>\n<p>그러나, 가장 먼저 현재 project 에게 <code class=\"docutils literal notranslate\">polls</code> app 이 설치되어 있다는 것을 알려야 합니다.</p>\n<aside class=\"admonition-philosophy admonition\" role=\"note\">\n<p class=\"admonition-title\">철학</p>\n<p>Django 의 app 들은 착탈 가능(“pluggable”) 합니다. app 을 다수의 프로젝트에서 사용할 수 있으며, app 을 배포할 수도 있습니다. 특정 Django 에 app 들이 묶여있지 않아도 되기 때문입니다.</p>\n</aside>\n<p>app 을 현재의 project 에 포함시키기 위해서는, app 의 구성 클래스에 대한 참조를 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 설정에 추가시켜야 합니다. <code class=\"docutils literal notranslate\">PollsConfig</code> 클래스는 <code class=\"file docutils literal notranslate\">polls/apps.py</code> 파일 내에 존재합니다. 따라서, 점으로 구분된 경로는 <code class=\"docutils literal notranslate\">'polls.apps.PollsConfig'</code> 가 됩니다. 이 점으로 구분된 경로를, <code class=\"file docutils literal notranslate\">mysite/settings.py</code> 파일을 편집하여 <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\">INSTALLED_APPS</code></a> 설정에 추가하면 됩니다. 이는 다음과 같이 보일것입니다.</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>mysite/settings.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"mysite/settings.py\"><code>INSTALLED_APPS <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"s1\">&#39;polls.apps.PollsConfig&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.admin&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.auth&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.contenttypes&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.sessions&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.messages&#39;</span><span class=\"p\">,</span>\n    <span class=\"s1\">&#39;django.contrib.staticfiles&#39;</span><span class=\"p\">,</span>\n<span class=\"p\">]</span>\n</code></pre></figure>\n<p>이제, Django 는 <code class=\"docutils literal notranslate\">polls</code> app 이 포함된 것을 알게 되었습니다. 다른 명령을 내려봅시다.</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py makemigrations polls\n</code></pre></div>\n<p>다음과 비슷한 것이 보일겁니다.:</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>Migrations for &#39;polls&#39;:\n  polls/migrations/0001_initial.py:\n    - Create model Choice\n    - Create model Question\n    - Add field question to choice\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">makemigrations</code> 을 실행시킴으로서, 당신이 모델을 변경시킨 사실과(이 경우에는 새로운 모델을 만들었습니다) 이 변경사항을 <em>migration</em> 으로 저장시키고 싶다는 것을 Django 에게 알려줍니다.</p>\n<p>migration 은 Django가 모델(즉, 데이터베이스 스키마를 포함한)의 변경사항을 저장하는 방법으로써, 디스크상의 파일로 존재합니다. 원한다면, <code class=\"docutils literal notranslate\">polls/migrations/0001_initial.py</code> 파일로 저장된 새 모델에 대한 migration 을 읽어볼 수 있습니다. 걱정하지 마십시요, Django 가 migration 을 만들때마다 직접 읽어보실 필요는 없습니다만, 수동으로 Django 의 변경점을 조정하고 싶을때 사람이 직접 변경할 수 있도록 설계되어 있습니다.</p>\n<p>당신을 위해 migration 들을 실행시켜주고, 자동으로 데이터베이스 스키마를 관리해주는 <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> 라는 명령어가 존재합니다. 이 명령을 알아보기 전에 migration 이 내부적으로 어떤 SQL 문장을 실행하는지 살펴봅시다. <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-sqlmigrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">sqlmigrate</code></a> 명령은 migration 이름을 인수로 받아, 실행하는 SQL 문장을 보여줍니다.</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py sqlmigrate polls <span class=\"m\">0001</span>\n</code></pre></div>\n<p>다음과 비슷한 결과를 보실 수 있습니다. (가독성을 위해 결과물을 조금 다듬었습니다)</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"SQL code\"><code><span class=\"k\">BEGIN</span><span class=\"p\">;</span>\n<span class=\"c1\">--</span>\n<span class=\"c1\">-- Create model Choice</span>\n<span class=\"c1\">--</span>\n<span class=\"k\">CREATE</span> <span class=\"k\">TABLE</span> <span class=\"ss\">&quot;polls_choice&quot;</span> <span class=\"p\">(</span>\n    <span class=\"ss\">&quot;id&quot;</span> <span class=\"nb\">serial</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span> <span class=\"k\">PRIMARY</span> <span class=\"k\">KEY</span><span class=\"p\">,</span>\n    <span class=\"ss\">&quot;choice_text&quot;</span> <span class=\"nb\">varchar</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">)</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span><span class=\"p\">,</span>\n    <span class=\"ss\">&quot;votes&quot;</span> <span class=\"nb\">integer</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span>\n<span class=\"p\">);</span>\n<span class=\"c1\">--</span>\n<span class=\"c1\">-- Create model Question</span>\n<span class=\"c1\">--</span>\n<span class=\"k\">CREATE</span> <span class=\"k\">TABLE</span> <span class=\"ss\">&quot;polls_question&quot;</span> <span class=\"p\">(</span>\n    <span class=\"ss\">&quot;id&quot;</span> <span class=\"nb\">serial</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span> <span class=\"k\">PRIMARY</span> <span class=\"k\">KEY</span><span class=\"p\">,</span>\n    <span class=\"ss\">&quot;question_text&quot;</span> <span class=\"nb\">varchar</span><span class=\"p\">(</span><span class=\"mi\">200</span><span class=\"p\">)</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span><span class=\"p\">,</span>\n    <span class=\"ss\">&quot;pub_date&quot;</span> <span class=\"k\">timestamp</span> <span class=\"k\">with</span> <span class=\"k\">time</span> <span class=\"k\">zone</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span>\n<span class=\"p\">);</span>\n<span class=\"c1\">--</span>\n<span class=\"c1\">-- Add field question to choice</span>\n<span class=\"c1\">--</span>\n<span class=\"k\">ALTER</span> <span class=\"k\">TABLE</span> <span class=\"ss\">&quot;polls_choice&quot;</span> <span class=\"k\">ADD</span> <span class=\"k\">COLUMN</span> <span class=\"ss\">&quot;question_id&quot;</span> <span class=\"nb\">integer</span> <span class=\"k\">NOT</span> <span class=\"k\">NULL</span><span class=\"p\">;</span>\n<span class=\"k\">ALTER</span> <span class=\"k\">TABLE</span> <span class=\"ss\">&quot;polls_choice&quot;</span> <span class=\"k\">ALTER</span> <span class=\"k\">COLUMN</span> <span class=\"ss\">&quot;question_id&quot;</span> <span class=\"k\">DROP</span> <span class=\"k\">DEFAULT</span><span class=\"p\">;</span>\n<span class=\"k\">CREATE</span> <span class=\"k\">INDEX</span> <span class=\"ss\">&quot;polls_choice_7aa0f6ee&quot;</span> <span class=\"k\">ON</span> <span class=\"ss\">&quot;polls_choice&quot;</span> <span class=\"p\">(</span><span class=\"ss\">&quot;question_id&quot;</span><span class=\"p\">);</span>\n<span class=\"k\">ALTER</span> <span class=\"k\">TABLE</span> <span class=\"ss\">&quot;polls_choice&quot;</span>\n  <span class=\"k\">ADD</span> <span class=\"k\">CONSTRAINT</span> <span class=\"ss\">&quot;polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id&quot;</span>\n    <span class=\"k\">FOREIGN</span> <span class=\"k\">KEY</span> <span class=\"p\">(</span><span class=\"ss\">&quot;question_id&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">REFERENCES</span> <span class=\"ss\">&quot;polls_question&quot;</span> <span class=\"p\">(</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">DEFERRABLE</span> <span class=\"k\">INITIALLY</span> <span class=\"k\">DEFERRED</span><span class=\"p\">;</span>\n\n<span class=\"k\">COMMIT</span><span class=\"p\">;</span>\n</code></pre></div>\n<p>다음을 참고하세요:</p>\n<ul class=\"simple\">\n<li><p>사용하는 데이터베이스에 따라서 출력결과는 다를 수 있습니다. 위의 출력결과는 PostgreSQL 에서 생성되었습니다.</p></li>\n<li><p>테이블 이름은 app 의 이름과 모델의 이름(소문자)이 조합되어 자동으로 생성됩니다. 이 경우, 앱의 이름인 <code class=\"docutils literal notranslate\">polls</code> 와 소문자로 표기된 모델의 이름인 <code class=\"docutils literal notranslate\">question</code> 과 <code class=\"docutils literal notranslate\">choice</code> 가 합쳐집니다. 이 동작을 재지정(override) 하여 수정할 수 있습니다.)</p></li>\n<li><p>기본 키(Primary, ID) 는 자동으로 추가됩니다. (역시 이 동작도 재지정(override) 할 수 있습니다.)</p></li>\n<li><p>관례에 따라, Django 는 외래 키(foreign key) 필드명에 <code class=\"docutils literal notranslate\">&quot;_id&quot;</code> 이름을 자동으로 추가합니다. (물론 이것도 재지정 할 수 있습니다.)</p></li>\n<li><p>외래 키 관계는 <code class=\"docutils literal notranslate\">FOREIGN KEY</code> 제약이 명시적으로 생성됩니다. 제약 조건 연기(<code class=\"docutils literal notranslate\">DEFERRABLE</code>) 에 대해서는 걱정하지 않으셔도 됩니다. 이것은 단순히 PostgreSQL 에게 transaction 이 끝날때까지 외래 키를 강제하지 말라고 알려주는 것 뿐입니다.</p></li>\n<li><p>사용하는 데이터베이스에 따라, 데이터베이스 고유의 필드타입이 조정됩니다. 따라서, 자동 증가 필드를 생성할 경우 <code class=\"docutils literal notranslate\">auto_increment</code> (MySQL), <code class=\"docutils literal notranslate\">serial</code> (PostgreSQL), <code class=\"docutils literal notranslate\">integer primary key autoincrement</code> (SQLite) 와 같이 사용하는 데이터베이스에 따라 적절한 필드타입이 자동으로 선택됩니다. 필드 명에 사용되는 인용부호도 상황에 따라 겹따옴표나 홑따옴표가 적절히 선택됩니다.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-sqlmigrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">sqlmigrate</code></a> 명령은 실제로 데이터베이스의 migration 을 실행하지는 않습니다. 이 명령은 단순히 결과만 출력할 뿐이며, Django 가 필요로 하는 SQL 이 무엇인지 확인할 수 있습니다. 이 결과를 이용하여 Django 가 무엇을 할 것인지 미리 확인하거나, 데이터베이스 관리자에게 필요한 SQL 스크립트를 요청할 수도 있습니다.</p></li>\n</ul>\n<p>관심이 있다면, <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-check\"><code class=\"xref std std-djadmin docutils literal notranslate\">python manage.py check</code></a> 명령을 통해 migration 을 생성하거나 데이터베이스를 건드리지 않고도 project 에서 문제를 확인할 수 있습니다.</p>\n<p>이제, <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> 를 실행시켜 데이터베이스에 모델과 관련된 테이블을 생성해봅시다.</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py migrate\n<span class=\"go\">Operations to perform:</span>\n<span class=\"go\">  Apply all migrations: admin, auth, contenttypes, polls, sessions</span>\n<span class=\"go\">Running migrations:</span>\n<span class=\"go\">  Rendering model states... DONE</span>\n<span class=\"go\">  Applying polls.0001_initial... OK</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">migrate</code></a> 명령은 아직 적용되지 않은 모든 migration 들을 수집하여 이를 실행합니다. (Django 는 migration 의 적용 여부를 기록하는 <code class=\"docutils literal notranslate\">django_migrations</code> 테이블이 있습니다) 이 과정을 통해 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어집니다.</p>\n<p>migration 은 매우 기능이 강력하여, 마치 project 를 개발 할 때처럼 데이터베이스나 테이블에 손대지 않고도 모델의 반복적인 변경을 가능하게 해줍니다. 동작중인 데이터베이스를 자료 손실 없이 업그레이드 하는데에 최적화 되어 있습니다. 튜토리얼의 나머지 부분에서 이 부분을 조금 더 살펴 보겠습니다만, 지금은 모델의 변경을 만드는 세단계의 지침을 기억하세요:</p>\n<ul class=\"simple\">\n<li><p>(<code class=\"docutils literal notranslate\">models.py</code> 에서) 모델을 변경합니다.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-makemigrations\"><code class=\"xref std std-djadmin docutils literal notranslate\">python manage.py makemigrations</code></a> 을 통해 이 변경사항에 대한 migration 을 만드세요.</p></li>\n<li><p><a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\">python manage.py migrate</code></a> 명령을 통해 변경사항을 데이터베이스에 적용하세요.</p></li>\n</ul>\n<p>migration 을 만드는 명령과, 적용하는 명령이 분리된 이유는 버전 관리 시스템에 migration 을 커밋할 수 있게 하여 app 과 함께 제공하기 위해서입니다. 이것은 단순히 당신의 개발을 쉽게 해주는 것 뿐 아니라, 다른 개발자들과 운영 환경에서도 유용하게 사용될 수 있습니다.</p>\n<p><a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/\"><span class=\"doc\">django-admin documentation</span></a> 문서에 <code class=\"docutils literal notranslate\">manage.py</code> 유틸리티가 어떤 일들을 할 수 있는지 알 수 있습니다.</p>\n</section>\n<section id=\"playing-with-the-api\">\n<h2>API 가지고 놀기<a class=\"heading-anchor\" href=\"#playing-with-the-api\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>이제, 대화식 Python 쉘에 뛰어들어 Django API 를 자유롭게 가지고 놀아봅시다. Python 쉘을 실행하려면 다음의 명령을 입력합니다:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py shell\n</code></pre></div>\n<p>단순히 “python” 이라고 실행하는 대신에, 위의 명령을 실행한 까닭은, <code class=\"file docutils literal notranslate\">manage.py</code> 에 설정된 <code class=\"docutils literal notranslate\">DJANGO_SETTINGS_MODULE</code> 환경변수 때문입니다. 이 환경변수는 <code class=\"file docutils literal notranslate\">mysite/settings.py</code> 파일에 대한 Python import 경로를 Django 에게 제공하여, 대화식 Python 쉘에서 Django 가 접근할 수 있는 Python 모듈 경로를 그대로 사용 할 수 있습니다. 즉, Django 에서 동작하는 모든 명령을 대화식 Python 쉘에서 그대로 시험해 볼 수 있습니다.</p>\n<aside class=\"admonition-bypassing-manage-py admonition\" role=\"note\">\n<p class=\"admonition-title\">manage.py 안 쓰기</p>\n<p>만약 <code class=\"file docutils literal notranslate\">manage.py</code> 파일을 사용하지 않더라도 문제는 없습니다. <span class=\"target\" id=\"index-2\"></span><a class=\"reference internal\" href=\"/ko/1.11/topics/settings/#envvar-DJANGO_SETTINGS_MODULE\"><code class=\"xref std std-envvar docutils literal notranslate\">DJANGO_SETTINGS_MODULE</code></a> 환경변수를 <code class=\"docutils literal notranslate\">mysite.settings</code> 에 설정하고, Python 쉘을 시작한 뒤, 다음과 같이 Django 를 설정하면 됩니다:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span> <span class=\"nn\">django</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>django<span class=\"o\">.</span>setup<span class=\"p\">()</span>\n</code></pre></div>\n<p>만약 <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#AttributeError\" title=\"(Python v3.14에서)\"><code class=\"xref py py-exc docutils literal notranslate\">AttributeError</code></a> 가 발생하면, 사용하고 있는 Django 의 버전과 이 튜토리얼에서 사용하는 버전이 다르기 때문일수도 있습니다. 사용하고 있는 Django 버전에 맞는 튜토리얼로 진행하든지, 현재 튜토리얼 버전에 맞는 Django 를 설치해주세요.</p>\n<p>단, 반드시 <code class=\"file docutils literal notranslate\">manage.py</code> 과 같은 디렉토리에서 <code class=\"docutils literal notranslate\">python</code> 을 실행하거나, Python 의 import path 에 해당 디렉토리가 추가되어야만 <code class=\"docutils literal notranslate\">import mysite</code> 가 제대로 동작합니다.</p>\n<p>위의 내용에 대한 더 자세한 정보는 <a class=\"reference internal\" href=\"/ko/1.11/ref/django-admin/\"><span class=\"doc\">django-admin documentation</span></a> 에서 참고해 주십시요.</p>\n</aside>\n<p>쉘에 진입한 후, <a class=\"reference internal\" href=\"/ko/1.11/topics/db/queries/\"><span class=\"doc\">database API</span></a> 를 탐험해 보세요:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">polls.models</span> <span class=\"kn\">import</span> Question<span class=\"p\">,</span> Choice   <span class=\"c1\"># Import the model classes we just wrote.</span>\n\n<span class=\"go\"># No questions are in the system yet.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet []&gt;</span>\n\n<span class=\"go\"># Create a new Question.</span>\n<span class=\"go\"># Support for time zones is enabled in the default settings file, so</span>\n<span class=\"go\"># Django expects a datetime with tzinfo for pub_date. Use timezone.now()</span>\n<span class=\"go\"># instead of datetime.datetime.now() and it will do the right thing.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> timezone\n<span class=\"gp\">&gt;&gt;&gt; </span>q <span class=\"o\">=</span> Question<span class=\"p\">(</span>question_text<span class=\"o\">=</span><span class=\"s2\">&quot;What&#39;s new?&quot;</span><span class=\"p\">,</span> pub_date<span class=\"o\">=</span>timezone<span class=\"o\">.</span>now<span class=\"p\">())</span>\n\n<span class=\"go\"># Save the object into the database. You have to call save() explicitly.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>save<span class=\"p\">()</span>\n\n<span class=\"go\"># Now it has an ID. Note that this might say &quot;1L&quot; instead of &quot;1&quot;, depending</span>\n<span class=\"go\"># on which database you&#39;re using. That&#39;s no biggie; it just means your</span>\n<span class=\"go\"># database backend prefers to return integers as Python long integer</span>\n<span class=\"go\"># objects.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>id\n<span class=\"go\">1</span>\n\n<span class=\"go\"># Access model field values via Python attributes.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>question_text\n<span class=\"go\">&quot;What&#39;s new?&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>pub_date\n<span class=\"go\">datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=&lt;UTC&gt;)</span>\n\n<span class=\"go\"># Change values by changing the attributes, then calling save().</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>question_text <span class=\"o\">=</span> <span class=\"s2\">&quot;What&#39;s up?&quot;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>save<span class=\"p\">()</span>\n\n<span class=\"go\"># objects.all() displays all the questions in the database.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Question: Question object&gt;]&gt;</span>\n</code></pre></div>\n<p>잠깐만요, <code class=\"docutils literal notranslate\">&lt;Question: Question object&gt;</code> 는 이 객체를 설명하는데에 정말 하나도 도움이 안되네요. (<code class=\"docutils literal notranslate\">polls/models.py</code> 파일의) <code class=\"docutils literal notranslate\">Question</code> 모델을 수정하여 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/instances/#django.db.models.Model.__str__\" title=\"django.db.models.Model.__str__\"><code class=\"xref py py-meth docutils literal notranslate\">__str__()</code></a> 메소드를 <code class=\"docutils literal notranslate\">Question</code> 과 <code class=\"docutils literal notranslate\">Choice</code> 에 추가해 봅시다.</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/models.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/models.py\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.utils.encoding</span> <span class=\"kn\">import</span> python_2_unicode_compatible\n\n<span class=\"nd\">@python_2_unicode_compatible</span>  <span class=\"c1\"># only if you need to support Python 2</span>\n<span class=\"k\">class</span> <span class=\"nc\">Question</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>question_text\n\n<span class=\"nd\">@python_2_unicode_compatible</span>  <span class=\"c1\"># only if you need to support Python 2</span>\n<span class=\"k\">class</span> <span class=\"nc\">Choice</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">def</span> <span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>choice_text\n</code></pre></figure>\n<p>당신의 모델에 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/instances/#django.db.models.Model.__str__\" title=\"django.db.models.Model.__str__\"><code class=\"xref py py-meth docutils literal notranslate\">__str__()</code></a> 메소드를 추가하는것은 객체의 표현을 대화식 프롬프트에서 편하게 보려는 이유 말고도, Django 가 자동으로 생성하는 관리 사이트 에서도 객체의 표현이 사용되기 때문입니다.</p>\n<p>이것들은 모두 보통의 Python 메소드입니다. 예시를 위해 수정된 메소드를 추가해 보겠습니다:</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/models.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/models.py\"><code><span class=\"kn\">import</span> <span class=\"nn\">datetime</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n<span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> timezone\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Question</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"k\">def</span> <span class=\"nf\">was_published_recently</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>pub_date <span class=\"o\">&gt;=</span> timezone<span class=\"o\">.</span>now<span class=\"p\">()</span> <span class=\"o\">-</span> datetime<span class=\"o\">.</span>timedelta<span class=\"p\">(</span>days<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></figure>\n<p><code class=\"docutils literal notranslate\">import datetime</code> 은 Python 의 표준 모듈인 <a class=\"reference external\" href=\"https://docs.python.org/3/library/datetime.html#module-datetime\" title=\"(Python v3.14에서)\"><code class=\"xref py py-mod docutils literal notranslate\">datetime</code></a> 모듈이며, <code class=\"docutils literal notranslate\">from django.utils import timezone</code> 은 Django  의 시간대 관련 유틸리티인 <a class=\"reference internal\" href=\"/ko/1.11/ref/utils/#module-django.utils.timezone\" title=\"django.utils.timezone: Timezone support.\"><code class=\"xref py py-mod docutils literal notranslate\">django.utils.timezone</code></a> 을 의미합니다. 만약 Python 에서 시간대를 조작하는 방법에 대해 익숙하지 않다면, <a class=\"reference internal\" href=\"/ko/1.11/topics/i18n/timezones/\"><span class=\"doc\">시간대 지원 문서</span></a> 에서 더 많은것을 배울 수 있습니다.</p>\n<p>변경된 사항을 저장하고, <code class=\"docutils literal notranslate\">python manage.py shell</code> 를 다시 실행해보세요:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">polls.models</span> <span class=\"kn\">import</span> Question<span class=\"p\">,</span> Choice\n\n<span class=\"go\"># Make sure our __str__() addition worked.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Question: What&#39;s up?&gt;]&gt;</span>\n\n<span class=\"go\"># Django provides a rich database lookup API that&#39;s entirely driven by</span>\n<span class=\"go\"># keyword arguments.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Question: What&#39;s up?&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>question_text__startswith<span class=\"o\">=</span><span class=\"s1\">&#39;What&#39;</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Question: What&#39;s up?&gt;]&gt;</span>\n\n<span class=\"go\"># Get the question that was published this year.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> timezone\n<span class=\"gp\">&gt;&gt;&gt; </span>current_year <span class=\"o\">=</span> timezone<span class=\"o\">.</span>now<span class=\"p\">()</span><span class=\"o\">.</span>year\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pub_date__year<span class=\"o\">=</span>current_year<span class=\"p\">)</span>\n<span class=\"go\">&lt;Question: What&#39;s up?&gt;</span>\n\n<span class=\"go\"># Request an ID that doesn&#39;t exist, this will raise an exception.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span><span class=\"nb\">id</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n<span class=\"gt\">Traceback (most recent call last):</span>\n    <span class=\"o\">...</span>\n<span class=\"gr\">DoesNotExist</span>: Question matching query does not exist.\n\n<span class=\"x\"># Lookup by a primary key is the most common case, so Django provides a</span>\n<span class=\"x\"># shortcut for primary-key exact lookups.</span>\n<span class=\"x\"># The following is identical to Question.objects.get(id=1).</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Question: What&#39;s up?&gt;</span>\n\n<span class=\"go\"># Make sure our custom method worked.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q <span class=\"o\">=</span> Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>was_published_recently<span class=\"p\">()</span>\n<span class=\"go\">True</span>\n\n<span class=\"go\"># Give the Question a couple of Choices. The create call constructs a new</span>\n<span class=\"go\"># Choice object, does the INSERT statement, adds the choice to the set</span>\n<span class=\"go\"># of available choices and returns the new Choice object. Django creates</span>\n<span class=\"go\"># a set to hold the &quot;other side&quot; of a ForeignKey relation</span>\n<span class=\"go\"># (e.g. a question&#39;s choice) which can be accessed via the API.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q <span class=\"o\">=</span> Question<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n\n<span class=\"go\"># Display any choices from the related object set -- none so far.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet []&gt;</span>\n\n<span class=\"go\"># Create three choices.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>create<span class=\"p\">(</span>choice_text<span class=\"o\">=</span><span class=\"s1\">&#39;Not much&#39;</span><span class=\"p\">,</span> votes<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Choice: Not much&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>create<span class=\"p\">(</span>choice_text<span class=\"o\">=</span><span class=\"s1\">&#39;The sky&#39;</span><span class=\"p\">,</span> votes<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n<span class=\"go\">&lt;Choice: The sky&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>create<span class=\"p\">(</span>choice_text<span class=\"o\">=</span><span class=\"s1\">&#39;Just hacking again&#39;</span><span class=\"p\">,</span> votes<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n\n<span class=\"go\"># Choice objects have API access to their related Question objects.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>question\n<span class=\"go\">&lt;Question: What&#39;s up?&gt;</span>\n\n<span class=\"go\"># And vice versa: Question objects get access to Choice objects.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>all<span class=\"p\">()</span>\n<span class=\"go\">&lt;QuerySet [&lt;Choice: Not much&gt;, &lt;Choice: The sky&gt;, &lt;Choice: Just hacking again&gt;]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>count<span class=\"p\">()</span>\n<span class=\"go\">3</span>\n\n<span class=\"go\"># The API automatically follows relationships as far as you need.</span>\n<span class=\"go\"># Use double underscores to separate relationships.</span>\n<span class=\"go\"># This works as many levels deep as you want; there&#39;s no limit.</span>\n<span class=\"go\"># Find all Choices for any question whose pub_date is in this year</span>\n<span class=\"go\"># (reusing the &#39;current_year&#39; variable we created above).</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Choice<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>question__pub_date__year<span class=\"o\">=</span>current_year<span class=\"p\">)</span>\n<span class=\"go\">&lt;QuerySet [&lt;Choice: Not much&gt;, &lt;Choice: The sky&gt;, &lt;Choice: Just hacking again&gt;]&gt;</span>\n\n<span class=\"go\"># Let&#39;s delete one of the choices. Use delete() for that.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c <span class=\"o\">=</span> q<span class=\"o\">.</span>choice_set<span class=\"o\">.</span>filter<span class=\"p\">(</span>choice_text__startswith<span class=\"o\">=</span><span class=\"s1\">&#39;Just hacking&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>c<span class=\"o\">.</span>delete<span class=\"p\">()</span>\n</code></pre></div>\n<p>모델의 관계에 대한 더 많은 정보는 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/relations/\"><span class=\"doc\">Accessing related objects</span></a> 를 참고하세요. API 에서 이중 밑줄(<code class=\"docutils literal notranslate\">__</code>) 을 이용해서 어떻게 필드를 조회할 수 있는지는 <a class=\"reference internal\" href=\"/ko/1.11/topics/db/queries/#field-lookups-intro\"><span class=\"std std-ref\">Field lookups</span></a> 를 읽어보세요.데이터베이스 API 에 대한 자세한 내용을 보시려면, <a class=\"reference internal\" href=\"/ko/1.11/topics/db/queries/\"><span class=\"doc\">Database API reference</span></a> 를 읽어보세요.</p>\n</section>\n<section id=\"introducing-the-django-admin\">\n<h2>Django Admin 모듈 소개<a class=\"heading-anchor\" href=\"#introducing-the-django-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"admonition-philosophy admonition\" role=\"note\">\n<p class=\"admonition-title\">철학</p>\n<p>직원들이나 고객들이 컨텐츠의 내용을 수정하기 위한 관리 사이트를 만드는것은 딱히 창의적일 필요없는 지루한 작업입니다. 이런 이유로, Django 는 모델에 대한 관리용 인터페이스를 모두 자동으로 생성합니다.</p>\n<p>Django 는 <code class=\"docutils literal notranslate\">Lawrence Journal-World</code> 신문사의 프로그래머가 처음 개발하였습니다. 이런 태생적인 이유 때문에, “컨텐츠 게시자” 와 “공개” 사이트의 구분이 명확합니다. 사이트 관리자는 뉴스 기사, 사건, 스포츠 경기 결과 같은 것들을 시스템에 추가합니다. 그렇게 추가된 컨텐츠는 “공개” 사이트에 노출됩니다. Django 는 사이트 관리자가 컨텐츠를 편집할 수 있는 통합적인 인터페이스를 생성하는 문제를 해결합니다.</p>\n<p>관리 사이트는 사이트 방문자를 위한 것이 아니라, 사이트 관리자를 위한 것입니다.</p>\n</aside>\n<section id=\"creating-an-admin-user\">\n<h3>관리자 생성하기<a class=\"heading-anchor\" href=\"#creating-an-admin-user\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>우선, 관리 사이트에 로그인 할 수 있는 사용자를 생성해 봅시다. 다음과 같은 명령을 수행합니다.</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py createsuperuser\n</code></pre></div>\n<p>원하는 username 을 입력하고 엔터를 누르세요</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>Username: admin\n</code></pre></div>\n<p>그런 다음 원하는 이메일 주소를 입력하라는 메시지가 표시됩니다.</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>Email address: admin@example.com\n</code></pre></div>\n<p>마지막으로, 암호를 입력하세요. 암호를 두번 물어보게 되는데, 두번째 입력하는 암호를 올바로 입력했는지를 확인하기 위한 암호입니다.</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>Password: **********\nPassword (again): *********\nSuperuser created successfully.\n</code></pre></div>\n</section>\n<section id=\"start-the-development-server\">\n<h3>개발 서버를 실행하세요<a class=\"heading-anchor\" href=\"#start-the-development-server\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 의 관리 사이트는 기본으로 활성화 되어 있습니다. 개발 서버를 켜고, 탐험해 봅시다.</p>\n<p>서버가 기동되지 않았다면 다음과 같이 보입니다:</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python manage.py runserver\n</code></pre></div>\n<p>이제, 웹 브라우져를 열고 로컬 도메인의 “/admin/” 으로 이동합니다. 예를들면, <a class=\"reference external\" href=\"http://127.0.0.1:8000/admin/\">http://127.0.0.1:8000/admin/</a> 으로 접근할 수 있습니다. 그럼 다음과 같이 로그인 화면이 보일겁니다.</p>\n<img alt=\"Django admin login screen\" src=\"/ko/1.11/_images/admin01.png\" />\n<p><a class=\"reference internal\" href=\"/ko/1.11/topics/i18n/translation/\"><span class=\"doc\">translation</span></a> 가 기본으로 켜져 있기 때문에, 로그인 화면은 당신의 브라우저의 설정에 따라 (Django 가 해당 언어의 번역본이 있다면) 번역된 언어로 표시될 것입니다.</p>\n</section>\n<section id=\"enter-the-admin-site\">\n<h3>관리자 사이트로 들어가세요<a class=\"heading-anchor\" href=\"#enter-the-admin-site\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>앞서 생성한 슈퍼유저(superuser) 계정으로 로그인 해봅시다. 다음과 같은 Django 관리 인덱스 페이지가 보일것입니다.</p>\n<img alt=\"Django admin index page\" src=\"/ko/1.11/_images/admin02.png\" />\n<p>편집 가능한 그룹과 사용자와 같은 몇 종류의 컨텐츠를 볼 수 있습니다. 이것들은 <a class=\"reference internal\" href=\"/ko/1.11/topics/auth/#module-django.contrib.auth\" title=\"django.contrib.auth: Django's authentication framework.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.auth</code></a> 모듈에서 제공되는데, Django 에서 제공되는 인증 프레임워크 입니다.</p>\n</section>\n<section id=\"make-the-poll-app-modifiable-in-the-admin\">\n<h3>관리 사이트에서 poll app 을 변경가능하도록 만들기<a class=\"heading-anchor\" href=\"#make-the-poll-app-modifiable-in-the-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>그런데, poll app 이 관리 인덱스 페이지에서 보이지 않네요. 어디에 있을까요?</p>\n<p>여기서 하나만 더 하면 됩니다. 관리 사이트에 <code class=\"docutils literal notranslate\">Question</code> 객체가 관리 인터페이스를 가지고 있다는것을 알려주는 것입니다. 이것을 하기 위해서는, <code class=\"file docutils literal notranslate\">polls/admin.py</code> 파일을 열어 다음과 같이 편집하면 됩니다.</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"default\"><figcaption class=\"code-block-caption\"><code>polls/admin.py</code></figcaption><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"polls/admin.py\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib</span> <span class=\"kn\">import</span> admin\n\n<span class=\"kn\">from</span> <span class=\"nn\">.models</span> <span class=\"kn\">import</span> Question\n\nadmin<span class=\"o\">.</span>site<span class=\"o\">.</span>register<span class=\"p\">(</span>Question<span class=\"p\">)</span>\n</code></pre></figure>\n</section>\n<section id=\"explore-the-free-admin-functionality\">\n<h3>자유로운 관리 기능을 탐색하기<a class=\"heading-anchor\" href=\"#explore-the-free-admin-functionality\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>이제, <code class=\"docutils literal notranslate\">Question</code> 을 등록시켰으니 Django 는 이를 알아채고 관리 인덱스 페이지에 이를 표시할 것입니다:</p>\n<img alt=\"Django admin index page, now with polls displayed\" src=\"/ko/1.11/_images/admin03t.png\" />\n<p>“Questions” 을 클릭하십시요. 그러면 질문들을 위한 “change list” 로 이동합니다. 이 페이지는 데이터베이스에 저장된 모든 질문들을 보여주며, 그 중 하나를 선택하여 변경할 수 있습니다. 이전에 등록했던 “What’s up?” 질문이 있을 것입니다.</p>\n<img alt=\"Polls change list page\" src=\"/ko/1.11/_images/admin04t.png\" />\n<p>“What’s up?” 질문을 클릭하여 수정합니다.</p>\n<img alt=\"Editing form for question object\" src=\"/ko/1.11/_images/admin05t.png\" />\n<p>여기서 알아둘 것들:</p>\n<ul class=\"simple\">\n<li><p>이 서식은 <code class=\"docutils literal notranslate\">Question</code> 모델에서 자동으로 생성되었습니다</p></li>\n<li><p>모델의 각 필드 유형들은 (<a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a>, <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.CharField\" title=\"django.db.models.CharField\"><code class=\"xref py py-class docutils literal notranslate\">CharField</code></a>) 적절한 HTML 입력 위젯으로 표현됩니다. 필드의 각 유형들은 Django 관리 사이트에서 어떻게 표현해되어야 할지 알고 있습니다.</p></li>\n<li><p>각각의 <a class=\"reference internal\" href=\"/ko/1.11/ref/models/fields/#django.db.models.DateTimeField\" title=\"django.db.models.DateTimeField\"><code class=\"xref py py-class docutils literal notranslate\">DateTimeField</code></a> 는 JavaScript 로 작성된 단축 기능과 연결됩니다. 날짜는 “오늘”(“Today”) 버튼과 달력 팝업에서 입력할 수 있으며, 시간은 “지금”(“Now”) 버튼과 일반적으로 입력하는 시간들을 제공하는 편리한 팝업을 통해서도 입력할 수 있습니다.</p></li>\n</ul>\n<p>페이지의 아래 부분에서 다음과 같은 몇가지 옵션을 제공합니다.</p>\n<ul class=\"simple\">\n<li><p>저장(Save) – 이 유형의 객체에 대한 변경사항을 저장하고, 변경된 목록 페이지를 보여줍니다</p></li>\n<li><p>저장 및 편집 계속(Save and continue editing) – 이 객체에 대한 변경사항을 저장하고, 현재 편집창을 갱신합니다</p></li>\n<li><p>저장 및 다른 이름으로 추가(Save and add another) – 변경사항을 저장하고, 이 유형의 객체에 대한 비어있는 새로운 입력창을 불러옵니다</p></li>\n<li><p>삭제(Delete) – 삭제를 확인하는 페이지를 띄웁니다.</p></li>\n</ul>\n<p>만약 “Date published” 의 값이 <a class=\"reference internal\" href=\"/ko/1.11/intro/tutorial01/\"><span class=\"doc\">Tutorial 1</span></a> 에서 질문을 생성했을때의 시간과 일치하지 않는다면, <a class=\"reference internal\" href=\"/ko/1.11/ref/settings/#std-setting-TIME_ZONE\"><code class=\"xref std std-setting docutils literal notranslate\">TIME_ZONE</code></a> (시간대) 설정을 깜빡 하신것일지도 모릅니다. 이 설정을 바꾸시고 다시 페이지를 불러오시면 올바른 값이 표현됩니다.</p>\n<p>“Date published” 의 값을 “오늘”(“Today”) 과 “지금”(“Now”) 단축버튼을 눌러 바꾸십시요. 그런 후, “저장 및 편집 계속”(“Save and continue editing”) 을 누르십시요. 그런 후, 우측 상단의 “히스토리”(“History”) 버튼을 누르십시요. Django 관리사이트를 통해 누가(username) 언제(timestamp) 무엇을 바꾸었는지 목록을 확인할 수 있습니다.</p>\n<img alt=\"History page for question object\" src=\"/ko/1.11/_images/admin06t.png\" />\n<p>모델 API 와 관리 사이트에 익숙해 지셨다면, <a class=\"reference internal\" href=\"/ko/1.11/intro/tutorial03/\"><span class=\"doc\">이 튜토리얼의 3번째 파트</span></a> 를 읽어 어떻게 polls 앱에 view 를 추가할 수 있는지 배워보세요.</p>\n</section>\n</section>","rootId":"writing-your-first-django-app-part-2","toc":[{"title":"데이터베이스 설치","anchor":"database-setup","children":[]},{"title":"모델 만들기","anchor":"creating-models","children":[]},{"title":"모델의 활성화","anchor":"activating-models","children":[]},{"title":"API 가지고 놀기","anchor":"playing-with-the-api","children":[]},{"title":"Django Admin 모듈 소개","anchor":"introducing-the-django-admin","children":[{"title":"관리자 생성하기","anchor":"creating-an-admin-user","children":[]},{"title":"개발 서버를 실행하세요","anchor":"start-the-development-server","children":[]},{"title":"관리자 사이트로 들어가세요","anchor":"enter-the-admin-site","children":[]},{"title":"관리 사이트에서 poll app 을 변경가능하도록 만들기","anchor":"make-the-poll-app-modifiable-in-the-admin","children":[]},{"title":"자유로운 관리 기능을 탐색하기","anchor":"explore-the-free-admin-functionality","children":[]}]}],"breadcrumbs":[{"docname":"intro/index","title":"시작하기","url":"/ko/1.11/intro/"}],"prev":{"docname":"intro/tutorial01","title":"첫 번째 장고 앱 작성하기, part 1","url":"/ko/1.11/intro/tutorial01/"},"next":{"docname":"intro/tutorial03","title":"첫 번째 장고 앱 작성하기, part 3","url":"/ko/1.11/intro/tutorial03/"},"formats":{"html":"/ko/1.11/intro/tutorial02/","markdown":"/ko/1.11/intro/tutorial02.md","json":"/ko/1.11/intro/tutorial02.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/intro/tutorial02.txt","official":"https://docs.djangoproject.com/ko/1.11/intro/tutorial02/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11"],"inLocales":["en","fr","ja","id","pt-br","ko","es","el","pl"]}