본문 바로가기
프로그래밍/Python

파이썬 웹프로그래밍 - 장고(Django) 데이터베이스 API 사용하기

by pentode 2018. 4. 21.

이 글은 앞의 글 "파이썬 웹프로그래밍 - 장고(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 튜토리얼 한글 문서"  에서 볼 수 있습니다.

반응형