장고(django)의 ORM

2019-06-03

장고(django)의 ORM(Object-Relational Mapping)을 사용하여 데이터를 생성하고 읽고 갱신하고 삭제하는 방법(CRUD - Create Read Update Delete)에 대해서 알아봅시다.

개요

장고(django)의 ORM(Object-Relational Mapping)을 사용하여 데이터베이스에 데이터를 생성(Create)하고, 읽고(Read), 갱신(Update)하고, 삭제(Delete)하는 방법(CRUD - Create Read Update Delete)에 대해서 알아봅니다.

이 블로그는 시리즈로 작성되어 있으며, 아래에 링크를 통해 시리즈의 다른 글을 확인할 수 있습니다.

또한 이 블로그 시리즈에서 다룬 소스는 github에 공개되어 있습니다. 아래에 링크를 통해 확인 가능합니다.

ORM이란?

ORM(Object-Relation Mapping)란, 객체(Object)관계형 데이터베이스(Relational)연결(Mapping)해 주는 것을 의미한다. 간단하게 설명하면 데이터베이스의 테이블을 객체(Object)와 연결하여 테이블에 CRUD를 할 때, SQL 쿼리를 사용하지 않고도, 가능하게 하는 것을 말합니다.

우리는 이전 블로그(장고(django) 모델(models) 사용해보기)를 통해 이미 장고(django)의 ORM(Object-Relational Mapping)을 사용하기 위한 준비를 하였습니다. 이전 블로그에서 생성한 Post 모델(Models)은 데이터베이스의 blog_post 테이블과 연결(Mapping)되어 있습니다. 우리는 이 모델(Models)을 사용하여 데이터베이스에 CRUD을 함으로써 장고(django)의 ORM(Object-Relational Mapping)을 이해해 보도록 하겠습니다.

아래에 장고(django) 명령어를 통해 장고(django)가 기본적으로 제공하는 쉘(Shell)을 실행 시킵니다.

# source venv/bin/activate
# cd django_exercise
python manage.py shell

아래에 코드로 우리가 이전 블로그에서 만든 Post 모델(Models)을 가져옵니다.

>>> from blog.models import Post

데이터 조회(Read)

아래에 코드로 Post의 내용을 조회(Read)합니다.

Post.objects.all()

정상적으로 실행되었다면 아래와 같은 결과를 볼 수 있습니다.

>>> Post.objects.all()
<QuerySet [<Post: this is a test1 title>, <Post: this is a test2 title>]>

나중에 사용하기 위해, 아래에 코드로 사용자(User) 모델(Models)을 가져오고, 데이터를 조회(Read)하여 변수에 저장합니다.

>>> from django.contrib.auth.models import User
>>> admin = User.objects.get(username='dev-yakuza')

데이터 생성(Create)

아래에 코드를 실행하여 Post의 새로운 데이터를 생성(Create)해 봅니다.

Post.objects.create(author=admin, title='This is a test title from django shell', content='This is a test title from django shell. This is a test title from django shell.')

정상적으로 실행되었다면 아래와 같은 결과를 볼 수 있습니다.

>>> Post.objects.create(author=admin, title='This is a test title from django shell', content='This is a test title from django shell. This is a test title from django shell.')
<Post: This is a test title from django shell>

데이터 생성 확인

다시 한번 Post 모델(Models)을 조회하면 아래와 같이 데이터가 잘 추가된 것을 확인 할 수 있습니다.

>>> Post.objects.all()
<QuerySet [<Post: this is a test1 title>, <Post: this is a test2 title>, <Post: This is a test title from django shell>]>

새로운 터미널에서 아래에 장고(django) 명령어로 테스트 서버를 실행한 후, 관리자 화면에서 데이터를 확인하면 아래와 같이 데이터가 잘 추가된 것을 확인할 수 있습니다.

# source venv/bin/activate
# cd django_exercise
python manage.py runserver

장고(django) 관리자 페이지에서 데이터 확인

데이터베이스 툴을 사용하여 확인해도 아래와 같이 저장이 잘 된 것을 확인할 수 있습니다.

데이터베이스 툴을 사용하여 데이터 확인

데이터 업데이트(Update)

아래에 코드로 데이터를 조회(Read)하고 업데이트(Update) 해 봅니다.

post = Post.objects.get(title='This is a test title from django shell')
post.title = 'This is a test title updated from django shell'
post.save()

아래에 코드로 업데이트된 내용을 확인할 수 있습니다.

Post.objects.get(title__contains='updated')
# or
Post.objects.filter(title__contains='updated')

또한 이전 블로그에서 작성한 Post 모델(Models)의 함수를 통해서도 업데이트가 가능합니다.

post = Post.objects.get(title__contains='updated')
# post.published_at
post.publish()
# >>> post.published_at
# datetime.datetime(2019, 5, 21, 13, 1, 58, 970677)

데이터 삭제(Delete)

아래에 코드로 위에서 만든 데이터를 삭제(Delete)해 봅니다.

post = Post.objects.get(title__contains='updated')
post.delete()
# >>> Post.objects.all()
# <QuerySet [<Post: this is a test1 title>, <Post: this is a test2 title>]>

조회 조건

지금까지 데이터베이스의 CRUD(Create Read Update Delete)에 대해서 살펴보았습니다. 아래는 데이터를 조회(Read)할 때 사용할 수 있는 일반적인 검색 조건에 대해서 설명하고 있습니다.

  • 조회 조건
조회 조건 설명 사용 방법
__contains 지정한 문자열을 포함하는 데이터 조회 Post.objects.filter(title__contains=’test’)
__icontains 지정한 문자열의 대소문자 구분없이 포함하는 데이터 조회 Post.objects.filter(title__icontains=’this’)
__lt 값이 작은 경우(lt: less than) Post.objects.filter(published_at__lt=timezone.now())
__lte 값이 작거나 같은 경우(lte: less than or equal) Post.objects.filter(published_at__lt=timezone.now())
__gt 값이 큰 경우(gt: greater than) Post.objects.filter(published_at__gt=timezone.now())
__gte 값이 크거나 같은 경우(gt: greater than or equal) Post.objects.filter(published_at__gte=timezone.now())
__in 주어진 리스트에 포함되는 데이터 조회 Post.objects.filter(id__in=[1, 2, 3])
__year 해당 년도 조회 Post.objects.filter(created_at__year=’2019’)
__year 해당 월로 조회 Post.objects.filter(created_at__month=’5’)
__day 해당 일로 조회 Post.objects.filter(created_at__day=’21’)
__isnull 해당 열이 null인 데이터 조회 Post.objects.filter(published_at__isnull=True)
__startswith 해당 문자열로 시작하는 데이터 조회 Post.objects.filter(title__startswith=’This’)
__istartswith 대소문자를 가리지 않고 해당 문자열로 시작하는 데이터 조회 Post.objects.filter(title__istartswith=’this’)
__endswith 해당 문자열로 끝나는 데이터 조회 Post.objects.filter(title__endswith=’title’)
__iendswith 대소문자를 가리지 않고 해당 문자열로 끝나는 데이터 조회 Post.objects.filter(title__iendswith=’title’)
__range 범위를 지정하여 조회(sql의 between) Post.objects.filter(id__range=(1, 10))
  • 제외 조건(exclude): 아래와 같이 특정 조건을 제외한 데이터를 조회할 수 있다.
Post.objects.all().exclude(title__contains='This')
  • 여러 조건으로 조회: 아래와 같이 여러 조건을 걸어 데이터를 조회할 수 있다.
Post.objects.filter(title__contains='this', title__endswith='title')
Post.objects.filter(title__contains='this').filter(title__endswith='title')

from django.db.models import Q
Post.objects.filter(Q(title__contains='this') | Q(title__endswith='title'))
Post.objects.filter(Q(title__contains='this') & Q(title__endswith='title'))
  • 조회 범위: 아래와 같이 가져올 데이터의 범위(limit)을 지정할 수 있다.
Post.objects.all().exclude(title__contains='This')[:1]

정렬

아래와 같이 조회할 데이터를 오름차순 또는 내림차순으로 정렬할 수 있습니다.

  • 오름 차순: Post.objects.order_by(‘created_at’)
  • 내림 차순: Post.objects.order_by(‘-created_at’)

쉘(Shell) 종료

지금까지 장고(django)의 쉘(Shell)을 이용하여 간단하게 장고(django)의 ORM(Object-Relational Mapping)에 대해서 연습해 보았습니다. 아래에 코드로 장고(django)의 쉘(Shell)을 종료합니다.

exit()

완료

이것으로 장고(django)의 ORM(Object-Relational Mapping)에 대해 알아보았습니다. ORM(Object-Relational Mapping)은 장고(django)이외에도 많은 프레임워크에서 사용되는 개념이므로 잘 기억에 두면 좋을거 같네요. 이것으로 우리는 장고(django)의 모델(Models)을 사용하여 데이터를 읽고 쓰고 업데이트하고 삭제(CRUD - Create Read Update Delete)할 수 있게 되었습니다!

Buy me a coffeeBuy me a coffee
Posts