이 글은 Django 공식 문서의 Getting Started를 참고하여 정리한 글입니다. ( 링크 )

또한 이전 글과 내용이 이어집니다. ( 링크 )



1. settings.py

본격적으로 개발하기 전에 프로젝트 전반적인 환경 설정을 해야 합니다.


Django는 기본적으로 sqlite3 DATABASE를 사용하지만, mysite/settings.py 파일을 통해 DB를 변경할 수 있습니다.

( 다른 DB를 변경하는 방법은 여기를 참고해주세요 ! )

여기서는 sqlite3를 그대로 사용합니다.



다음으로 polls 애플리케이션을 프로젝트에 등록해야 합니다.

INSTALLED_APPS 리스트에 polls 애플리케이션 이름을 작성합니다.

애플리케이션 이름은 생성한 애플리케이션의 apps.py 파일에 작성되어 있습니다.


INSTALLED_APPS는 현재 Django 인스턴스에 활성화된 모든 Django 애플리케이션의 이름들이 나열되어 있습니다.

애플리케이션은 다수의 프로젝트에서 사용할 수 있으므로, 설정 파일에서 등록을 해야 합니다.


기본적으로 제공하는 app은 다음과 같습니다.

1) django.contrib.admin              : admin 페이지 사이트

2) django.contrib.auth                  : 인증 시스템

3) django.contrib.contenttypes   : 컨텐츠 타입을 위한 프레임워크

4) django.contrib.sessions            : 세션 프레임워크

5) django.contrib.message          : 메세징 프레임워크

6) django.contrib.staticfiles         : 정적 파일을 관리하는 프레임워크



그리고 TIME_ZONE 값을 변경하여, 시스템 시간을 세계 표준 시인 UTC에서 한국 시간으로 바꾸도록 하겠습니다.


이상으로 예제를 작성하기 위한 설정 파일을 수정해보았습니다.





2. 모델 생성

이제, 설문조사 애플리케이션에 필요한 모델을 만들어 보겠습니다.

Question 모델은 설문 내용( question_text )과 발행일( pub_date ) 두 필드를 가지며, 

Choice 모델은 설문 선택지( choice_text )와 투표 수( votes ) 두 필드를 가집니다.


또한 Question과 Choice는 1 : N 관계에 있기 때문에, Choice 모델에는 Question의 PK를 FK로 가져야 합니다.


이 내용은 models.py 파일에 작성이 되며, 코드로 표현하면 다음과 같습니다.

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')

def __str__(self):
return self.question_text

class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)

def __str__(self):
return self.choice_text

테이블은 클래스와 매핑되고, 테이블의 칼럼은 클래스의 변수로 매핑됩니다.

그리고 클래스를 테이블로 정의하려면, django.db.models.Model 클래스를 상속받아 정의해야 합니다.


각 테이블의 PK는 Django에서 자동으로 생성해줍니다. ( Not Null , Autoincrement )

Django가 생성해준 PK이름은 규칙이 있는데,

예를 들어 Choice 테이블의 PK 이름은 choice_id 이며, 테이블 명의 접두어를 소문자 처리하고 _id를 추가하는 방식입니다.


Question과 Choice는 1 : N 관계이기 때문에 Choice 테이블에서 Question의 PK를 외래키로 가져야 합니다.

Django에서는 models.ForeignKey()를 호출하여 인자로 클래스 명을 전달하면 됩니다.


여기서 on_delete는, 참조하고 있는 테이블이 삭제될 때 어떤 행동을 취할 것인지 정의하는데, 무결성과 관련하여 필요한 작업입니다.

지금은 CASCADE 방식을 사용했으며, 다른 방법에 대해서는 여기를 참고해주세요 !

또한 __str__을 작성한 이유는, 조금 뒤에 살펴 볼 Django Shell에서 객체 표현을 편하게 출력하려는 이유가 있고,
Django가 자동으로 생성하는 admin 페이지에서도 객체의 표현이 사용되기 때문입니다.



models.py 파일을 작성한 것은 단순히 테이블을 정의만 한 것이고, DB에 물리적으로 실제로 반영하기 위해서는 migration을 해야 합니다.

$ python manage.py makemigrations $ python manage.py migrate

makemigrations을 명령어를 실행하면, 모델이 변경된 사실을 Django에게 알려주는 역할을 합니다.

생성된 polls/migrations/0001_initial.py 파일을 열어보면 model.py 파일에서 작성한 모델이 등록되어 있는 것을 확인할 수 있습니다.

또한 0001_initial.py 파일을 통해 개발자가 직접 모델을 변경할 수 있습니다.



다음으로 migrate 명령어를 통해 모델의 변경사항들과 database 상태를 동기화 할 수 있습니다.


또한 다음의 명령어를 통해 Django가 생성한 SQL을 확인할 수 있습니다.

( ORM에서 개발자가 원하는대로 SQL이 생성되었는지 확인하는 것은 중요합니다. )

# python manage.py sqlmigrate pools 0001



지금까지 DB 테이블을 작성하고, 이를 반영해보았는데 정리하자면 다음과 같습니다.

1) models.py 파일에서 모델을 작성

2) makemigrations 명령어를 통해 변경 사항에 대한 migrations을 만듦

3) migrate 명령어를 통해 변경 사항을 DB에 적용


migration을 생성하는 명령과, 적용하는 명령이 분리된 이유는 버전 관리 시스템에 migration 을 커밋할 수 있게 하여 애플리케이션과 함께 제공하기 위해서입니다.





3. Django Shell로 데이터 조작

위에서 모델을 생성했고, 이전 글에서는 admin 페이지에서 데이터를 조작하는 방법에 대해 알아보았습니다.

간단한 데이터 조작은 admin 페이지로 하는 것이 좋지만, 복잡한 데이터 처리 및 인터넷 연결이 좋지 않은 경우 쉘로 처리하는 것이 좋습니다.


이를 Django Shell이라 하는데, Django Shell을 사용하려면 아래의 명령어를 입력하면 됩니다.

$ python manage.py shell


이 쉘은 일반 파이썬 쉘과 차이점이 있습니다.

Django Shell은 manage.py에서 정의한 DJANGO_SETTINGS_MODULE 속성을 이용하여 미리 settings.py 모듈을 import합니다.

따라서 Django Shell을 이용하면, 데이터 조작이 가능합니다.

[ manage.py ]


이제 Django Shell을 이용하여 데이터를 조작하는 명령어들을 알아보겠습니다.

1) Create
쉘 상에서 import를 한 후, 모델을 생성할 때 필드 값을 인자로 넘겨줘서 테이블 객체를 생성합니다.
그리고 DB에 반영하기 위해서는 save() 메서드를 호출하는데, 내부적으로 SQL INSERT가 수행됩니다.

 

 

2) Read
데이터를 조회하기 위해서는 QuerySet 객체를 사용합니다.
QuerySet은 테이블로부터 가져 온 객체들의 collection인데, QuerySet은 필터( filter )를 통해 주어진 조건에 맞는 레코드만 다시 추출할 수 있습니다.
SQL로 따지면, QuerySet은 SQL SELECT와 같고, filter는 WHERE, LIMIT와 같습니다.

QuerySet을 얻기 위해서는 objects객체를 사용하면 되는데, objects는 테이블 정보를 담고 있는 객체입니다.
또한 QuerySet은 chaining이 가능합니다.


모든 레코드 반환

테이블의 모든 레코드를 반환하려면 objects.all() 메서드를 호출하면 됩니다.

 

필터 사용

말 그대로 레코드를 조회할 때 필터를 사용합니다.

즉 SQL에서 Where과 비슷한 역할을 합니다.


위 명령어는 id=3인 레코드만 조회 하도록 필터링을 합니다.

반대로 아래 명령어는 id=3를 제외한 레코드만 조회 하도록 필터링을 합니다.



1개의 레코드만 조회

get() 메서드를 호출하면 1개의 레코드만 조회할 수 있습니다.



Limit, Offest

Limit과 Offest을 사용하는 방법은 Python의 자료형인 리스트를 슬라이싱 하는 방법과 같습니다.


[ a : b ] 에서 Offset은 a에 해당하며, Limit은 b에 해당합니다.



1 : N 관계에 있는 테이블의 모든 레코드 조회

Question과 Choice는 1 : N 관계에 있는데, N에 해당하는 테이블은 xxx_set 형식의 이름으로 접근이 가능합니다.

즉 Question과 Choice가 1 : N 관계에 있으므로, Question.choice_set 으로 접근하여 한 Question의 id 값을 FK로 갖는 Choice Query Set을 얻을 수 있습니다.



반대로 자식쪽에서 부모 객체를 얻을 수도 있습니다.




3) Update

Update는 Create와 마찬가지로 save() 메서드를 호출하면 됩니다.


 

4) Delete

데이터를 삭제하려면 delete() 메서드를 호출하면 됩니다.


 


이상으로 Django에서 모델을 생성하는 방법, 즉 migration에 대해 알아보았습니다.

그리고 admin 페이지가 아닌, Shell로서 데이터를 조작하는 Django Shell에 대해서도 알아보았습니다.


다음 글에서는 본격적으로 Django의 View와 Templete를 작성하여 설문조사 애플리케이션을 구현해보겠습니다.


[ 참고 ]

https://docs.djangoproject.com/ko/2.0/intro/