We.TIL 18 : Django Tutorial#2

김기욱·2020년 8월 3일
0

데이터베이스 설치

장고는 기본적으로 데이터베이스로 SQLite를 사용하도록 구성되어 있다. 만약 데이터베이스를 처음 경험해보거나, Django에서 데이터베이스를 한 번 경험해 보고 싶다면 SQLite가 가장 간단한 방법이다. 만약 다른 데이터베이스를 사용해보고 싶다면, 적절한 데이터베이스 바인딩을 설치하고, 데이터베이스 연결 설정과 맞게끔 DATABASE 'default' 항목의 값을 다음의 키 값으로 바꿔주면 된다. (mysite/settings.py 활용)

  • ENGINE - 'django.db.backends.sqlite3' 'django.db.backends.postgresql', 'django.db.backends.mysql', 'django.db.backends.oracle' 등...
  • NAME - 데이터베이스의 이름. 만약 SQLite를 사용 중이라면, 데이터베이스는 당신의 컴퓨터의 파일로서 저장된다. 이 경우, NAME은 파일명을 포함한 절대경로로 지정해야 한다. 기본값은 os.path.join(BASE_DIR, 'db.sqlite3')로 정의되어 있으며, 프로젝트 디렉토리 내에 db.sqlite3로 저장된다.

주의 : SQLite를 데이터베이스로 사용하지 않는 경우, USER, PASSWORD, HOST 같은 추가 설정이 반드시 필요합니다.

mysite/settings.py를 편집할 때, 당신의 시간대에 맞춰 TIME_ZONE값을 설정해야 한다.
또한, 이 파일의 윗 쪽에 있는 INSTALLED_APPS에 대해 언급하자면, 이 파일은 현재 Django 인스턴스에서 활성화된 모든 Django 어플리케이션의 이름이 담겨있다.

기본적으로 INSTALLED_APPS는 다음과 같은 앱을 포함한다.

  • django.contrib.admin : 관리용 사이트
  • django.contrib.auth : 인증시스템
  • django.contrib.contenttypes : 컨텐츠 타입을 위한 프레임워크
  • django.contrib.sessions : 세션 프레임워크
  • django.contrib.messages : 메세징 프레임워크
  • django.contrib.staticfiles : 정적파일을 관리하는 프레임워크

이러한 기본 어플리케이션들 중 몇몇은 최소한 하나 이상의 데이터베이스 테이블을 사용하는데, 그러기 위해서는 데이터베이스에서 테이블을 미리 만들 필요가 있다. 이를 위해, 다음 명령을 실행해보자.

python manage.py migrate

모델 만들기

모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조(layout)을 말한다.
폴 앱에서 우리는 두가지 모델을 만들게 될 것이다. Question&Choice가 그것이다. Question은 질문과 게제자료를 포함하고 있다. Choice는 두 가지 필드를 가지게 된다. Choice&Vote에 대한 문자들이다. 각각의 Choice는 Question과 연관되어 있다.

보다싶이 모델의 구성요소는 class와 subclass로 정의된다. 각각의 모델은 수 많은 속성들을 가지고 있고, 이러한 속성들은 모델 안에 데이터베이스를 나타내준다. 데이터의 각 필드는 Field 클래스의 인스턴스로서 표현됩니다. CharField는 문자(character)필드를 표현하고, DateTimeField는 날짜와 시간필드를 표현한다. 이것은 각 필드가 어떤 자료형을 가질 수 있는지를 Django에게 말해준다

각각의 Field인스턴스의 이름(question_text or pub_date)은 기계가 읽기 좋은 형식의 데이터베이스 필드 이름이다. 이 필드명을 파이썬 코드에서도 사용할 수 있으며, 데이터베이스에서 컬럼명으로 사용할 것이다.

몇몇 Field클래스들은 필수 인수가 필요하다. 예를 들어 CharField의 경우 max_length를 입력해 주어야 한다. 이것은 데이터베이스 스키마에서만 필요한 것이 아닌 값을 검증할때도 쓰이게 된다. 또한 Field는 다양한 선택적 인수들을 가질 수 있다. 이 예제에서는, default로 하여금 votes의 기본값을 0으로 설정하였다. 마지막으로 ForeignKey를 사용한 관계설정에 대해 설명을 하자면, 이 예제에서는 각각의 Choice가 하나의 Question에 관계 된다는 것을 Django에게 알려준다. Django는 다대일, 다대다, 일대일과 같은 모든 일반 데이터베이스의 관계들을 지원한다.

모델의 활성화

모델에 대한 이 작은 코드가, Django에게는 상당한 양의 정보를 전달한다. 장고는 이 정보를 가지고 다음과 같은 일을 할 수 있다.

  • 이 앱을 위한 데이터베이스 스키마 생성(CREATE TABLE 문)
  • Question과 Choice 객체에 접근하기 위한 Python 데이터베이스 접근 API 생성

그러나, 가장 먼저 현재 프로젝트에게 polls앱이 설치되어 있다는 것을 알려야 한다. 앱을 현재의 프로젝트에 포함시키기 위해서는, 앱의 구성 클래스에 대한 참조를 INSTALLED_APPS 설정에 추가해야 한다. Pollsconfig 클래스는 polls/apps.py 파일 내에 존재한다. 따라서, 점으로 구분된 경로는 'polls.apps.PollsConfig'가 된다. 이 점으로 구분된 경로를 mysite/settings.py 파일을 편집하여 INSTALLED_APPS 설정에 추가하면 된다.

이제 장고는 polls앱이 포함된 것을 알게 되었다. 다른명령을 내려보자.
python manage.py makemigrations polls라는 명령어를 입력하면 다음과 비슷한 것이 보일것이다.

makemigrations을 실행시킴으로서, 당신이 모델을 변경시킨 사실과 이 변경사항을 migration으로 저장시키고 싶다는것을 장고에게 알려주게 된다. 당신을 위해 migration을 실행시켜주고, 자동으로 데이터베이스 스키마를 관리해주는 migrate 명령어가 있다. 이 명령을 알아보기 전에 migration이 내부적으로 어떤 SQL문장을 실행하는지 살펴보자. sqlmigrate 명령은 migrate 이름을 인수로 받아, 실행하는 SQL 문장을 보여준다.

python manage.py sqlmigrate polls 0001

다음을 명심해라.

  • 사용하는 데이터베이스에 따라 출력결과는 다를 수 있다. 위의 출려결과는 PostSQL에서 생성되었다.
  • 테이블 이름은 앱의 이름과 모델의 이름(소문자)이 조합되어 자동으로 생성된다. 이 경우, 앱의 이름인 polls와 소문자로 표기된 모델의 이름인 question과 choice가 합쳐진다.
  • 기본 키가 자동으로 추가된다.
  • 관례에 따라, Django는 외래 키 필드명에 "_id" 이름을 자동으로 추가한다.
  • 사용하는 데이터베이스에 따라 데이터베이스 고유의 필드타입이 조정된다. 따라서, 자동 증가 필드를 생성할 경우 auto_increment(MySQL), serial(PostgreSQL), integer primary key autoincrement(SQLite)와 같이 사용되는 데이터베이스에 따라 적절한 필드타입이 자동으로 선택된다.
  • sqlmigrate 명령어는 사실 migration을 당신의 데이터베이스에서 실행시키는게 아니다. 대신, 이 명령어는 변경사항을 프린트해서 스크린 화면으로 띄워준다. 그래서 당신은 SQL장고가 무엇이 필요한지 확인할 수 있다.

Python manage.py migrate는 아직 적용되지 않은 마이그레이션을 모두 수집해 이를 실행하며 이 과정을 통해 모델에서의 변경사항들과 데이터베이스의 스키마의 동기화가 이루어진다. 마이그레이션은 매우 기능이 강력하며, 마치 프로젝트를 개발할 때 처럼 데이터베이스나 테이블에 손 대지 않고도 모델의 반복적인 변경을 가능케 한다. 마이그레이션과 관련된 모델의 변경을 만드는 세 단계 지침을 반드시 기억하자.

1단계 : (models.py에서) 모델을 변경한다
2단계 : python manage.py makemigrations를 통해 이 변경사항에 대한 마이그레이션을 만든다
3단계 : python manage.py migrate 명령을 통해 변경사항을 데이터베이스에 적용한다

API 다루기

파이썬 쉘을 실행하면 다음의 명령어를 입력하자. python manage.py shell
대화식 파이썬 쉘이 실행되며, 파이썬 모듈의 경로를 그대로 사용할 수 있다. 또한 Django에 동작하는 모든 명령을 대화식 파이썬 쉘에서 그대로 시험해 볼 수 있다.

polls/model.py의 Question 모델을 수정하여 __str__()메소드를 Question과 Choice에 추가해보자.

당신의 모델에 __str__()를 추가하는 것은 장고가 자동으로 생성하는 관리사이트에서도 객체의 표현이 사용되기 때문이다. 또한 커스텀메소드인 datetime을 추가해보자.

import datetime은 파이썬 표준 모듈인 datetime 모듈을, from django.utils import timezone은 장고의 시간대 관련 유틸리티인 django.utils.timezone을 참조하기 위해 추가한 것이다.

>>> from polls.models import Choice, Question

# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

# Create three 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)

# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
profile
어려운 것은 없다, 다만 아직 익숙치않을뿐이다.

0개의 댓글