- INSTALLED_APPS 는 Django와 함께 딸려오는 다음의 app들을 포함한다.

여기에서 각 model은 django.db.models의 class를 뒷받침 해주는 class로 표시됩니다. 각 모델에는 여러 class 변수가 있으며 각 변수는 모델의 database field를 나타낸다.
class Field 의 인스턴스로서 표현됩니다.
CharField는 string field를 표현하여 question_text 와 choice_text 에 필수인수(mat_length) 200을 입력해주었다.
date published 자료형을 가지도록 해주었다.각각의 Field 인스턴스의 이름(question_text 또는 pub_date) 은 기계가 읽기 좋은 형식(machine-friendly format) 의 database field 의 이름입니다. 이 인스턴스의 이름은 database에서 column명 으로 사용할 것이다.
모델에 대한 이 작은 코드가, Django에게는 상당한 양의 정보를 전달합니다.
앱을 현재의 프로젝트에 포함시키기 위해서는, 앱의 구성 클래스에 대한 참조를 INSTALLED_APPS 설정에 추가해야 합니다. PollsConfig 클래스는 polls/apps.py 파일 내에 존재합니다. 따라서, 점으로 구분된 경로는 polls.apps.PollsConfig가 됩니다. 이 점으로 구분된 경로를, Wecode/settings.py 파일을 편집하여 INSTALLED_APPS 설정에 추가하면 됩니다.

이제 Django는 polls앱이 포함된 것을 알게되었다.
$ python manage.py makemigrations polls command 입력makemigrations 을 실행시킴으로서, 당신이 모델을 변경시킨 사실과(지금의 경우는 새로운 모델을 만들었다.) 이 변경사항을 migration으로 저장시키고 싶다는 것을 Django에게 알려줍니다.

$ python manage.py sqlmigrate polls 0001sqlmigrate command는 migration 이름을 인수로 받아, 실행하는 SQL 문장을 보여줍니다.

ForeginKey
class ForeignKey(to, on_delete, **options)다대일 관계이고 두 가지 위치 인수가 필요합니다. model이 관련된 클래스와 on_delete 옵션이다. 재귀 관계를 만들기 위해서는(자신과 다대일 관계가 있는 객체)model.ForeignKey("self", on_delete=models.CASCADE)를 사용한다.
ForeignKey.on_delete
user = models.ForeginKey( Users, models.SET_NULL, blank = True, null = True, )ForeignKey 로 참조된 객체가 삭제될 때, Django는 on_delete 인수에 정의된 SQL 제약 조건의 동작을 에뮬레이션 한다. Null이 허용된 ForeignKey가 있고 참조된 객체가 삭제될 때 null 세팅하기 원할경우 위에있는 형식이 된다.
auto_increment(MySQL), serial(PostgreSQL), integer primary key autoincrement(SQLite)와 같이 사용하는 데이터베이스에 따라 적절한 필드타입이 자동으로 선택됩니다. 필드 명에 사용되는 인용부호도 상황에 따라 겹따옴표나 홑따옴표가 적절히 선택됩니다.python manage.py check command를 통해 migration 을 수행하거나 database를 건드리지 않고도 project의 문제를 확인할수있다.
$ python manage.py migrate command 입력migrate 명령은 아직 적용되지 않은 마이그레이션을 모두 수집해 이를 실행하며(Django는 django_migrations 테이블을 두어 마이그레이션 적용 여부를 추적합니다) 이 과정을 통해 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어집니다

python manage.py makemigrations를 통해 이 변경사항에 대한 migration을 만든다.python manage.py mirate command를 통해 변경사항을 데이터베이스에 적용Python shell로 Django API를 만져본다.
$ python manage.py shell command
단순히 python 이라고 실행 하는대신 manage.py shell 이 붙어있는 이유는 manage.py 에 설정된 DJANGO_SETTINGS_MODULE 환경변수 때문이다.
이 환경변수는 Wecode/settings.py 파일에 대한 Python import path를 Django에 제공하여, Python shell에서 Django가 접근할 수 있는 Python module path 를 그대로 사용 할 수 있다.

Django에서 동작하는 모든 명령을 Python shell에서 그대로 시험해 볼 수 있다.
from polls.models import Choice, Question
## 작성한 polls/models.py 에서 class Choice와 Question을 import 한다.
## 아직 시스템에 questions 가 없다.
>>> Question.objects.all()
<QuerySet []>
# 새로운 Question을 만든다.
# 표준 설정 파일에서 표준 시간대 지원이 활성화되어 있으므로 Djangosms pub_date 에 tzinfo 를 사용하여 날짜 시간을 예상한다.
# Timezone.now()를 사용한다.
# Python 의 datetime.datetime 객체에는 시간대 정보를 저장하는 데 사용할 수 있는 tzinfo 속성이 있으며 datetime.tzinfo의 하위 클래스 인스턴스로 표시된다.


>>> from django.utils import timezone
>>> q = Question(question_text = "What's new?", pub_date = timezone.now()
>>>q.save()
# obeject를 database에 저장하려면 .save()를 명시적으로 호출해야 한다.
>>>q.id
(출력값) 1
# .save()를 호출하지않고 id를 출력하면 아무것도 출력되지않는다. 하지만 호출하여 저장하면 1 이라는 ID값을 가지고있는것을 볼수있다.
>>> q.question_text
# 위에 class Question에 question_text 는 "What's new?"라는 값을 저장했기때문에 "What's new? 가 출력이된다.
>>> q.pub_date
# pub_date 는 datetime.datetime.now() 와 같은 timezone.now()를 저장했고
# 출력은
datetime.datetime(2020, 6, 7, 9, 42, 32, 936058, tzinfo=<UTC>) datetime과 같은값이 나온다.
>>> q.question_text = "What's up?"
# 다시 q.question_text에 "What's up?" 을 새로 입력해준뒤 .save()를 호출하여 저장한다.
>>> q.save()
# objects.all()은 database의 모든 question을 출력한다.
>>> Question.objects.all()
# <QuerySet [<Question: Question object (1)>]>
위의 <QuerySet [<Question: Question object (1)>]>은 이 객체를 표현하는데 별로다 Question model을 수정하여 __str__()method 를 Question과 Choice에 추가해준다.

models.py에 __str__() method를 추가하는것은 객체의 표현을 대화식 prompt에서 편하게 보려는 이유 말고도, Django가 자동으로 생성하는 관리 사이트 에서도 객체의 표현이 사용되기 때문이다.
이번엔 custom method 도 추가해보자.

import datetime 은 python 의 표준 모듈은 datetime 모듈을
from django.utils import timezone 은 Django의 시간대 관련 유틸리티인 django.utils.timezone을 참조하기 위해 추가했다.
추가했으니 다시한번 shell에서 실행해본다.
>>> from polls.models import Question, Choice
# __str__() method를 추가했으니 동작하는지 확인해본다.
>>> Question.objects.all()
<QuerySet [<Question: What`s up?>]>
# Django는Keyword arguments에 의해 구동되는 database 조회 API를 제공한다.
>>> Question.objects.filter(id=1)
id의 1에 해당하는 객체 출력
<QuerySet [<Question: What`s up?>]>
>>> Question.objects.filter(question_text__startswith = "What")
# 질문에서 What으로 시작하는 객체 출력
<QuerySet [<Question: What`s up?>]>
# 올해 질문된 질문을 출력할수도있다.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
# 현재기준으로 년도를 받는다.(2020)
>>> Question.objects.get(pub_date__year = current_year)
# pub_date__year 또한 2020이기떄문에 출력은 같다.
<Question: What`s up?>
# 존재하지않은 id를 입력하면 error가 발생한다.
>>> Question.objects.get(id=2)
# polls.models.Question.DoesNotExist: Question matching query does not exist.
먼저 관리자 생성을 합니다 $ python manage.py createsuperuser
Username: admin
Email address: admin@example.com
Password: ******** len(Password) > 7
이렇게 초기설정으로 superuser를 생성합니다.
로컬도메인의 /admin/ 으로 이동(http://127.0.0.1:8000/admin/)
하지만 들어가게되면 아직 poll app이 보이지않는다. register등록을 해줘야된다.
