이 글은 앞의 글 "파이썬 웹프로그래밍 - 장고(Django) 튜토리얼 1(MySQL, MariaDB 연동)" 에 이어집니다.
대화식 Python Shell 에서 Django 데이터베이스 API를 테스트 해봅니다. 명령창을 열어서 앞에서 만든 샘플 프로젝트의 src 폴더에 들어가서 다음 명령을 실행합니다.
D:\workspace\mysite\src\python manage.py shell
단순히 python만 실행하여 쉘을 띄우지 않는 이유는 manage.py 에 설정된 DJANGO_SETTINGS_MODULE 환경변수를 사용할 수 있게 하기 위해서 입니다. 이 환경에는 샘플 프로젝트에서 만든 데이터베이스 연결정보 객체 정보를 바로 사용할 수 있습니다.
1. 모델 임포트하고 Question 객체 생성하기
# 예제 사이트의 모델들을 임포트 합니다.
>>> from polls.models import Question, Choice
# 모든 설문을 조회합니다.
>>> Question.objects.all()
<QuerySet []>
# 새로운 설문을 만듭니다.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# 데이터를 저장합니다.
>>> q.save()
# 자동증가 필드인 ID가 생성되었습니다.
>>> q.id
1
2. Question 객체의 속성 값을 조회하고 변경하기
# 파이썬 속성을 사용해서 모델의 필드 값을 조회한다.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2018, 2, 6, 5, 11, 57, 384912, tzinfo=<UTC>)
# 속성값을 변경하여 저장한다.
>>> q.question_text = "What's up?"
>>> q.save()
# 모든 데이터를 출력해본다.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
3. 객체의 내용을 출력할 메소드를 만듭니다.
마지막 출력 내용은 봐도 도움이 되지 않습니다. polls/models.py 의 Question 모델을 수정하여 __str__() 메소드를 추가합니다.
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
객체 표현을 대화식 프롬프트에서 편하게 보려는 의도가 있고, Django가 자동으로 생성하는 관리 사이트에서도 객체의 표현이 사용됩니다. __str__() 메소드는 객체 자체를 출력할때 자동으로 호출되어지는 특수한 파이썬 메소드입니다. 데모를 위해 사용자 정의 메소드를 추가해 봅니다. 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)
추가된 import datetime과 from django.utils import timezone은 파이썬의 표준 datetime 모듈과 장고의 django.utils.timezone에 들어있는 타임존 관련 유틸리티를 각각 참조합니다. 이 변경사항을 저장하고 명령창에서 python manage.py shell을 다시 실행합니다.
>>> from polls.models import Question, Choice
# 추가한 __str__() 가 동작합니다.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
4. Question 객체를 검색하는 방법 알아보기
# 장고는 키워드를 인자로 줘서 사용되는 풍부한 데이터베이스 검색 API 를 제공합니다.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text_startswitch='What')
<QuerySet [<Question: What's up?>]>
# 올해에 만들어진 설문을 조회합니다.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# 존재하지 않는 ID에 대한 요청은 예외를 발생시킵니다.
>>> Question.objects.get(id=2)
Traceback )most recent call last):
...
DoesNotExist: Question matching query does not exist.
# 주키로 찾는 것은 가장 일반적인 경우 입니다.
# 그래서 장고는 주키와 일치하는 것을 찾는 지름길을 제공합니다.
# 아래는 Question.objects.get(id=1)과 동등합니다.
>>> Question.objects.get(pk=1)
<Question: What's up?>
# 우리의 사용자 정의 메소드를 사용해 봅시다.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
5. Choice 객체를 생성하고, 부모 객체인 Question에 접근하는 방법을 알아 봅니다.
# 설문에 몇가지 선택 항목(Choice 객체)을 추가 합니다. create 메소드의 호출은 새로운
# Choice 객체를 생성하고, INSERT 문으로 데이터베이스에 데이터를 넣고, Choice 객체 집합에
# 추가하고, 새로 만들어진 Choice 객체를 반환합니다. Django 는 외래키 관계의 다른편의
# 데이터(Question 객체에 종속되는 Choice 객체)를 저장할 집합을 만듭니다.
# 이것은 API를 통해 접근 가능합니다.
>>> q = Question.objects.get(pk=1)
# q 객체에 관련된 모든 Choice 객체를 표시합니다.
>>> q.choice_set.all()
<QuerySet []>
# 세 개의 Choice 객체를 만듭니다.
>>> 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 객체들은 자신의 부모 Question 객체에 접근하는 API 를 가집니다.
>>> c.question
<Question: What's up?>
# 그리고 Question 객체는 자신이 가지는 Choice객체들에 접근할 수 있습니다.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
6. 이중 밑줄(__)을 사용하여 속성을 추적하는 방법 알아보기
# API는 필요한 만큼 자동으로 관계를 따라갑니다. 관계를 분리하기 위해서 두 개의 밑줄을 사용하세요.
# 이것은 제한 없이 레벨을 따라 갈 수 있습니다.
# Question의 pub_date가 올해일 모든 질문을 찾으세요.(앞의 'current_year' 를 재사용합니다.)
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# delete() 메소드를 사용해서 Choice 객체들중 하나를 삭제합니다.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
※ 참조 링크
- 모델 관계에 대한 더 많은 정보 : https://docs.djangoproject.com/ko/2.0/ref/models/relations/
- 이중 밑줄(__)을 사용하는 방법 : https://docs.djangoproject.com/ko/2.0/topics/db/queries/#field-lookups-intro
- 데이터베이스 API : https://docs.djangoproject.com/ko/2.0/topics/db/queries/
2017년 6월 4일에 장고(Django)를 공부해보려고 시작하면서 글을 썻었습니다. 하지만 한 번 글을 쓰고는 계속 진행을 못하다가 해가 바껴서야 다시 보게 되었습니다. 그때 Django의 버전은 1.11 을 사용했었는데, Django 2.0 으로 업그레이드 되어 있고, 조금씩 바뀐 부분도 있더군요.
장고 튜토리얼을 따라해보고 있는데, 이게 한글 문서도 있었습니다. 전에도 있었는지는 모르겠지만, 영문 문서 보느라 괜히 고생했다 싶어 좀 허무 하더군요. "장고 2.0 튜토리얼 한글 문서" 에서 볼 수 있습니다.
'프로그래밍 > Python' 카테고리의 다른 글
Fedora 37 + Visual Studio Code환경에서 Python패키지 설치와 가상환경 사용하기(feat. matplotlib, tkinter) (0) | 2023.06.05 |
---|---|
Python 3.10.2와 PyScripter 설치하기 (0) | 2022.02.24 |
파이썬 문법 9 - 클래스(class) 만들기 (0) | 2018.04.09 |
파이썬 문법 8 - 모듈(module)과 패키지(package) 사용하기 (6) | 2018.04.09 |
파이썬 웹프로그래밍 - 장고(Django) 튜토리얼 1(MySQL, MariaDB 연동) (0) | 2018.04.09 |