mysite/settings.py
django 설정을 모듈 변수로 표현한 모듈
기본적으로 SQLite를 사용하도록 구성되어 있다. (기본적으로 제공되기 때문에 설치할 필요 X)
다른 데이터베이스를 사용할 경우,
1. 적절한 데이터베이스 바인딩을 설치 (MySQL - sqlclient)
2. DATABASES 'default' 항목의 값을 다음의 키 값으로 바꾼다.
django.db.backends.sqlite3
, django.db.backends.postgresql
, django.db.backends.mysql
, 또는 django.db.backends.oracle
. 그외에 서드파티 백엔드 참조.예시
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
데이터베이스 추가 설정 참고
https://docs.djangoproject.com/ko/3.1/ref/settings/#std:setting-DATABASES
INSTALLED_APPS
아래 앱들은 기본으로 제공된다.
필요하지 않은 항목은migrate
실행하기 전에 주석처리하거나 삭제해도 무방하다.
django.contrib.admin
관리용 사이트
django.contrib.auth
인증 시스템
django.contrib.contenttypes
컨텐츠 타입을 위한 프레임워크
django.contrib.sessions
세션 프레임워크
django.contrib.messages
메세징 프레임워크
django.contrib.staticfiles
정적파일을 관리하는 프레임워크
+) mysite/settings.py
를 편집할 때, 본인의 시간대에 맞춰 TIME_ZONE 값을 설정한다.
migrate 실행해준다.
$ python manage.py migrate
Migrations: 모델에 생긴 변화(필드추가, 모델삭제 등)를 반영하는 django의 방식
migrate
아직 적용되지 않은 migration을 모두 수집해서 실행할 때makemigrations
새로운 migrations을 만들 때sqlmigrate
migration을 sql 구문으로 볼 때showmigrations
프로젝트의 migration과 상태를 리스트업할 때
모델은 데이터의 필수적인 필드들과 동작들을 포함한다.
# polls/models.py
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 모델을 ForeignKey로 참조한다
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
데이터베이스의 각 필드는 Field 클래서의 인스턴스로 표현된다.
CharField
문자필드 (필수 인수: max_length)
DateTimeField
날짜와 시간 필드
선택적 인수로는 default 등이 있고, ForeinKey
로 관계설정이 가능하다.
현재 프로젝트에게 polls 앱이 설치되어 있다는 것을 알려준다.
앱을 현재의 프로젝트에 포함시키기 위해서는, 앱의 구성 클래스에 대한 참조를 INSTALLED_APPS 설정에 추가해야 한다.
# mysite/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig', # PollsConfig 클래스를 경로로 추가
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
$ python manage.py makemigrations polls
SQL 문장으로 확인해본다.
$ python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL,
"question_id" integer NOT NULL
);
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;
ex. polls_question, polls.choice
"_id"
이름을 자동으로 추가한다.이제 migration을 실행/적용 시켜준다.
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Rendering model states... DONE
Applying polls.0001_initial... OK
$ python manage.py shell
데이터베이스 API
>>> from polls.models import Choice, Question
>>> Question.objects.all() # Question 클래스의 객체 보기
<QuerySet []>
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save() # 위에서 생성한 object인 q 저장
>>> q.id # 저장했으므로 id를 가짐
1
# object field value 알아보기
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# value 변경 후 저장
>>> q.question_text = "What's up?"
>>> q.save()
# 이제는 객체 1개 나옴
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
객체 표현에 변화를 주기 위해,
__str__()
메소드 추가 > django가 자동으로 생성하는 관리사이트에서도 객체의 표현이 사용됨
# polls/models.py
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
모델에 timezone
도 추가
# polls/models.py
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
다시 Shell을 열고
>>> from polls.models import Choice, Question
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]> # 추가된 __str__() 확인
# filter: database lookup API
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
# get (올해 publish된 객체 가져오기)
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# 요청한 조건에 만족하는 객체가 없을 경우, exception 발생
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# primary key
>>> Question.objects.get(pk=1)
<Question: What's up?>
# was_published_recently()
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently() # 24시간 내에 publish된 것인가
True
# ForeignKey 참조하기
>>> q = Question.objects.get(pk=1)
# 자신(Question)을 참조하는 모델이 'lowercase_set'의 형태로 접근한다. > choice_set
# choice 객체의 개수를 묻는 것
>>> q.choice_set.all()
<QuerySet []> # 아직 없다.
# 3개의 choices 만들기
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
# c가 참조한 question object 보여주기
>>> c.question
<Question: What's up?>
# choice 객체 불러오기
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
# 올해 publish된 Choice 가져오기 (관계를 구분하기위해 '__')
# current_year = timezone.now().year
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# 객체 지우기
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
Field lookups (
__
: double-underscore)
# 관리자 생성
$ python manage.py createsuperuser
# 관리자 계정 만들기
Username: admin
Email address: admin@example.com
Password: **********
Password (again): *********
Superuser created successfully.
# 서버 켜고 'http://127.0.0.1:8000/admin/' 접속
$ python manage.py runserver
아래 보이는 컨텐츠들은 django.contrib.auth
모듈에서 제공
poll app을 관리 인덱스 페이지에 띄우려면,
# polls/admin.py
from django.contrib import admin
from .models import Question
admin.site.register(Question)