diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..be32386
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,112 @@
+# Created by https://www.toptal.com/developers/gitignore/api/pycharm
+# Edit at https://www.toptal.com/developers/gitignore?templates=pycharm
+
+### PyCharm ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+.idea
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### PyCharm Patch ###
+# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
+
+# *.iml
+# modules.xml
+# .idea/misc.xml
+# *.ipr
+
+# Sonarlint plugin
+# https://plugins.jetbrains.com/plugin/7973-sonarlint
+.idea/**/sonarlint/
+
+# SonarQube Plugin
+# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
+.idea/**/sonarIssues.xml
+
+# Markdown Navigator plugin
+# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
+.idea/**/markdown-navigator.xml
+.idea/**/markdown-navigator-enh.xml
+.idea/**/markdown-navigator/
+
+# Cache file creation bug
+# See https://youtrack.jetbrains.com/issue/JBR-2257
+.idea/$CACHE_FILE$
+
+# CodeStream plugin
+# https://plugins.jetbrains.com/plugin/12206-codestream
+.idea/codestream.xml
+
+# End of https://www.toptal.com/developers/gitignore/api/pycharm
\ No newline at end of file
diff --git a/README.md b/README.md
index 85dad61..879dbf7 100644
--- a/README.md
+++ b/README.md
@@ -1,16 +1,22 @@
# Start Django ✨
[Django Documentation Tutorial](https://docs.djangoproject.com/ko/3.2/intro/)을 따라가며 코드 및 배운 내용을 기록합니다.
-
+- **기간** : 2021.08.23 ~ 2021.08.27
+- **목적** : Django 프레임 워크 기본 기능 익히기
+- **순서**
+ 1. Django 공식 문서를 참고하여 실습 진행
+ 2. 배운 내용 문서로 정리
+ 3. 매일 아침 8:40 스크럼 회의
+ 4. 피드백 반영하여 코드 및 문서 수정
## Django
> Django makes it easier to build better Web apps more quickly and with less code.
-- **Development Environment**
- - Python 3.9.6
- - Django 3.2.6
+**Development Environment**
+- Python 3.9.6
+- Django 3.2.6
diff --git a/docs/02-database_and_admin.md b/docs/02-database_and_admin.md
new file mode 100644
index 0000000..24e06b9
--- /dev/null
+++ b/docs/02-database_and_admin.md
@@ -0,0 +1,288 @@
+# 02. Database and Admin
+
+데이터 베이스 설치 및 관리자 사이트 생성
+
+## 데이터베이스 설치
+
+- django는 기본적으로 SQLite : `mysite/settings.py`
+ ```python
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': BASE_DIR / 'db.sqlite3',
+ }
+ }
+ ```
+- 다른 데이터베이스 사용 시 [공식 문서](https://docs.djangoproject.com/ko/3.2/ref/settings/#std:setting-DATABASES) 참고
+ ```python
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.postgresql',
+ 'NAME': 'mydatabase',
+ 'USER': 'mydatabaseuser',
+ 'PASSWORD': 'mypassword',
+ 'HOST': '127.0.0.1',
+ 'PORT': '5432',
+ }
+ }
+ ```
+
+- `TIME_ZONE` 설정
+ ```python
+ TIME_ZONE = 'Asia/Seoul'
+ ```
+
+
+
+- `INSTALLED_APPS` 확인
+ ```python
+ INSTALLED_APPS = [
+ 'django.contrib.admin', # 관리용 사이트
+ 'django.contrib.auth', # 인증 시스템
+ 'django.contrib.contenttypes', # 컨텐츠 타입을 위한 프레임워크
+ 'django.contrib.sessions', # 세션 프레임워크
+ 'django.contrib.messages', # 메세징 프레임워크
+ 'django.contrib.staticfiles', # 정적 파일을 관리하는 프레임워크
+ ]
+ ```
+
+- 데이터베이스 설치 (`INSTALLED_APPS`에 대해서만)
+ ```bash
+ $ python manage.py migrate
+ ```
+
+
+
+## 모델 만들기
+
+- **모델** : 부가적인 메타데이터를 가진 데이터베이스의 구조 (layout)
+- 우리의 `polls`앱에서는 `Question` 과 `Choice`라는 두 가지 모델을 생성할 것.
+
+
+
+- `polls/models.py`
+ ```python
+ 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)
+ ```
+
+- 각 데이터베이스 필드를 `Field` 클래스의 인스턴스로 표현
+- `ForeignKey()` : 외래키 참조
+
+
+
+- `INSTALLED_APPS`에 `polls.apps.PollsConfig` 추가
+```bash
+$ python manage.py makemigrations polls
+Migrations for 'polls':
+ polls\migrations\0001_initial.py
+ - Create model Question
+ - Create model Choice
+```
+
+- `polls/migrations/0001_initial.py` 파일 생성 확인
+- SQL 명령어 확인
+ - app 이름과 모델명을 이용해 테이블 이름 자동 생성됨.
+ - 필드명, 필드 타입 관례에 따라 자동 생성
+```bash
+$ 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;
+```
+
+- 데이터베이스 모델 관련 테이블 생성하기 (변경사항 데이터베이스에 적용)
+```bash
+$ python manage.py migrate
+Operations to perform:
+ Apply all migrations: admin, auth, contenttypes, polls, sessions
+Running migrations:
+ Applying polls.0001_initial... OK
+```
+
+
+
+## 데이터베이스 API 사용하기
+
+```bash
+$ python manage.py shell
+Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)]
+Type 'copyright', 'credits' or 'license' for more information
+IPython 7.25.0 -- An enhanced Interactive Python. Type '?' for help.
+```
+```python
+In [1]: from polls.models import Choice, Question
+
+In [2]: Question.objects.all()
+Out[2]:
+
+In [3]: from django.utils import timezone
+
+In [4]: q = Question(question_text="What's new?", pub_date=timezone.now())
+
+In [5]: q.save()
+
+In [6]: q.id
+Out[6]: 1
+
+In [7]: q.question_text
+Out[7]: "What's new?"
+
+In [8]: q.pub_date
+Out[8]: datetime.datetime(2021, 8, 24, 8, 12, 43, 552040, tzinfo=)
+
+In [9]: q.question_text = "What's up?"
+
+In [10]: q.save()
+
+In [11]: Question.objects.all()
+Out[11]: ]>
+```
+
+- timezone을 `Asia/Seoul`로 설정했음에도 `UTC`로 표시됨 발견
+- `settings.py`에서 `USE_TZ = False`로 변경 → 해결됨
+
+```python
+In [8]: q.pub_date
+Out[8]: datetime.datetime(2021, 8, 24, 17, 49, 58, 504533)
+```
+
+- 객체 표현법 변경
+```python
+# polls/models.py
+
+# Question
+def __str__(self):
+ return self.question_text
+
+# Choice
+def __str__(self):
+ return self.choice_text
+```
+- 커스텀 메서드 추가
+```python
+def was_published_recently(self):
+ return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
+```
+
+
+
+- 커스텀 메서드 확인 및 api 다루기
+- 이중 밑줄 (`__`)을 이용한 필드 조회
+
+```bash
+$ python manage.py shell
+Python 3.9.6 (tags/v3.9.6:db3ff76, Jun 28 2021, 15:26:21) [MSC v.1929 64 bit (AMD64)]
+Type 'copyright', 'credits' or 'license' for more information
+IPython 7.25.0 -- An enhanced Interactive Python. Type '?' for help.
+```
+```python
+In [1]: from polls.models import Choice, Question
+
+In [2]: Question.objects.all()
+Out[2]: ]>
+
+In [3]: Question.objects.filter(id=1)
+Out[3]: ]>
+
+In [4]: Question.objects.filter(question_text__startswith='What')
+Out[4]: ]>
+
+In [5]: from django.utils import timezone
+
+In [6]: current_year = timezone.now().year
+
+In [7]: Question.objects.get(pub_date__year=current_year)
+Out[7]:
+
+In [8]: Question.objects.get(pk=1) # primary key
+Out[8]:
+
+In [9]: q = Question.objects.get(pk=1)
+
+In [10]: q.was_published_recently()
+Out[10]: True
+```
+
+- choice 추가하기
+```python
+In [11]: q.choice_set.all()
+Out[11]:
+
+In [12]: q.choice_set.create(choice_text='Not much', votes=0)
+Out[12]:
+
+In [13]: q.choice_set.create(choice_text='The sky', votes=0)
+Out[13]:
+
+In [14]: c = q.choice_set.create(choice_text='Just hacking again', votes=0)
+
+In [15]: c.question
+Out[15]:
+
+In [16]: q.choice_set.all()
+Out[16]: , , ]>
+
+In [17]: q.choice_set.count()
+Out[17]: 3
+
+In [18]: Choice.objects.filter(question__pub_date__year=current_year)
+Out[18]: , , ]>
+
+In [19]: c = q.choice_set.filter(choice_text__startswith='Just hacking')
+
+In [20]: c.delete()
+Out[20]: (1, {'polls.Choice': 1})
+```
+
+## 관리자 생성하기
+```bash
+$ python manage.py createsuperuser
+Username (leave blank to use 'user'): admin
+Email address: chaeyeonhee@kakao.com
+Password:
+Password (again):
+Superuser created successfully.
+```
+
+
+
+- 개발 서버 : http://127.0.0.1:8000/admin/
+```bash
+- $ python manage.py runserver
+Watching for file changes with StatReloader
+Performing system checks...
+
+System check identified no issues (0 silenced).
+August 24, 2021 - 19:56:57
+Django version 3.2.6, using settings 'mysite.settings'
+Starting development server at http://127.0.0.1:8000/
+Quit the server with CTRL-BREAK.
+[24/Aug/2021 19:57:21] "GET /admin/ HTTP/1.1" 302 0
+...
+```
diff --git a/mysite/db.sqlite3 b/mysite/db.sqlite3
index e69de29..0ab4cac 100644
Binary files a/mysite/db.sqlite3 and b/mysite/db.sqlite3 differ
diff --git a/mysite/mysite/__pycache__/__init__.cpython-39.pyc b/mysite/mysite/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000..16ffc23
Binary files /dev/null and b/mysite/mysite/__pycache__/__init__.cpython-39.pyc differ
diff --git a/mysite/mysite/__pycache__/settings.cpython-39.pyc b/mysite/mysite/__pycache__/settings.cpython-39.pyc
new file mode 100644
index 0000000..e27fdc2
Binary files /dev/null and b/mysite/mysite/__pycache__/settings.cpython-39.pyc differ
diff --git a/mysite/mysite/__pycache__/urls.cpython-39.pyc b/mysite/mysite/__pycache__/urls.cpython-39.pyc
new file mode 100644
index 0000000..0152486
Binary files /dev/null and b/mysite/mysite/__pycache__/urls.cpython-39.pyc differ
diff --git a/mysite/mysite/__pycache__/wsgi.cpython-39.pyc b/mysite/mysite/__pycache__/wsgi.cpython-39.pyc
new file mode 100644
index 0000000..c84bdf4
Binary files /dev/null and b/mysite/mysite/__pycache__/wsgi.cpython-39.pyc differ
diff --git a/mysite/mysite/settings.py b/mysite/mysite/settings.py
index 6ebe44d..53ea25f 100644
--- a/mysite/mysite/settings.py
+++ b/mysite/mysite/settings.py
@@ -31,6 +31,7 @@
# Application definition
INSTALLED_APPS = [
+ 'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
@@ -105,13 +106,13 @@
LANGUAGE_CODE = 'en-us'
-TIME_ZONE = 'UTC'
+TIME_ZONE = 'Asia/Seoul'
USE_I18N = True
USE_L10N = True
-USE_TZ = True
+USE_TZ = False
# Static files (CSS, JavaScript, Images)
diff --git a/mysite/mysite/urls.py b/mysite/mysite/urls.py
index 4552108..0698963 100644
--- a/mysite/mysite/urls.py
+++ b/mysite/mysite/urls.py
@@ -14,8 +14,10 @@
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
-from django.urls import path
+from django.urls import path, include
urlpatterns = [
+ # route : url 패턴
+ path('polls/', include('polls.urls')), # 다른 url 패턴을 포함할 때 include 함수 사용
path('admin/', admin.site.urls),
]
diff --git a/mysite/polls/__pycache__/__init__.cpython-39.pyc b/mysite/polls/__pycache__/__init__.cpython-39.pyc
index f7a8766..e892ef2 100644
Binary files a/mysite/polls/__pycache__/__init__.cpython-39.pyc and b/mysite/polls/__pycache__/__init__.cpython-39.pyc differ
diff --git a/mysite/polls/__pycache__/admin.cpython-39.pyc b/mysite/polls/__pycache__/admin.cpython-39.pyc
new file mode 100644
index 0000000..7122fd3
Binary files /dev/null and b/mysite/polls/__pycache__/admin.cpython-39.pyc differ
diff --git a/mysite/polls/__pycache__/apps.cpython-39.pyc b/mysite/polls/__pycache__/apps.cpython-39.pyc
new file mode 100644
index 0000000..e252dd3
Binary files /dev/null and b/mysite/polls/__pycache__/apps.cpython-39.pyc differ
diff --git a/mysite/polls/__pycache__/models.cpython-39.pyc b/mysite/polls/__pycache__/models.cpython-39.pyc
new file mode 100644
index 0000000..6a76737
Binary files /dev/null and b/mysite/polls/__pycache__/models.cpython-39.pyc differ
diff --git a/mysite/polls/__pycache__/urls.cpython-39.pyc b/mysite/polls/__pycache__/urls.cpython-39.pyc
index 225b681..513f7ee 100644
Binary files a/mysite/polls/__pycache__/urls.cpython-39.pyc and b/mysite/polls/__pycache__/urls.cpython-39.pyc differ
diff --git a/mysite/polls/__pycache__/views.cpython-39.pyc b/mysite/polls/__pycache__/views.cpython-39.pyc
index 87e4b42..0e63f11 100644
Binary files a/mysite/polls/__pycache__/views.cpython-39.pyc and b/mysite/polls/__pycache__/views.cpython-39.pyc differ
diff --git a/mysite/polls/admin.py b/mysite/polls/admin.py
index 8c38f3f..aa3fdc6 100644
--- a/mysite/polls/admin.py
+++ b/mysite/polls/admin.py
@@ -1,3 +1,4 @@
from django.contrib import admin
+from .models import Question
-# Register your models here.
+admin.site.register(Question)
\ No newline at end of file
diff --git a/mysite/polls/migrations/0001_initial.py b/mysite/polls/migrations/0001_initial.py
new file mode 100644
index 0000000..18ab3b2
--- /dev/null
+++ b/mysite/polls/migrations/0001_initial.py
@@ -0,0 +1,32 @@
+# Generated by Django 3.2.6 on 2021-08-24 17:48
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Question',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('question_text', models.CharField(max_length=200)),
+ ('pub_date', models.DateTimeField(verbose_name='date Published')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Choice',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('choice_text', models.CharField(max_length=200)),
+ ('votes', models.IntegerField(default=0)),
+ ('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.question')),
+ ],
+ ),
+ ]
diff --git a/mysite/polls/migrations/__pycache__/0001_initial.cpython-39.pyc b/mysite/polls/migrations/__pycache__/0001_initial.cpython-39.pyc
new file mode 100644
index 0000000..a9c4a00
Binary files /dev/null and b/mysite/polls/migrations/__pycache__/0001_initial.cpython-39.pyc differ
diff --git a/mysite/polls/migrations/__pycache__/__init__.cpython-39.pyc b/mysite/polls/migrations/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000..8eb54ec
Binary files /dev/null and b/mysite/polls/migrations/__pycache__/__init__.cpython-39.pyc differ
diff --git a/mysite/polls/models.py b/mysite/polls/models.py
index 71a8362..30ea737 100644
--- a/mysite/polls/models.py
+++ b/mysite/polls/models.py
@@ -1,3 +1,24 @@
+import datetime
+
from django.db import models
+from django.utils import timezone
+
+
+class Question(models.Model):
+ question_text = models.CharField(max_length=200)
+ pub_date = models.DateTimeField('date Published')
+
+ def __str__(self):
+ return self.question_text
+
+ def was_published_recently(self):
+ return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
+
+
+class Choice(models.Model):
+ question = models.ForeignKey(Question, on_delete=models.CASCADE)
+ choice_text = models.CharField(max_length=200)
+ votes = models.IntegerField(default=0)
-# Create your models here.
+ def __str__(self):
+ return self.choice_text