IT/WEB

[Django] Django의 ORM(Object-Relation Mapping)

개발자 두더지 2020. 9. 18. 00:29
728x90

 이번 포스팅에서는 Django의 ORM(Object-Relational Mapping)을 사용하여 데이터 베이스에 데이터를 생성(Create)하거나, 읽거나(Read), 갱신(Update)하거나, 삭제(Delete)하는 방법(CRUD-Create Read Update Delete)에 대해서 설명하도록 하겠다.

 

ORM이란?


 ORM(Object-Relation Mapping)이란 객체와 관계형 데이터 베이스를 Mapping하는 것을 의미한다. 간단히 말하자면 데이터 베이스의 테이블과 객체를 연결하여 테이블에서 CRUD할 때, SQL쿼리를 사용하지 않아도 되도록 하는 것이다. 아래의 커맨드를 실행시켜 shell을 이용하여 설명하고자한다.

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

 그리고 Model을 import한다.

>>> from blog.models import Post

 참고로 모델을 다음과 같이 작성했었다. (원작성자의 Model 작성관련 포스팅은 여기를 참고하길 바란다.) 

from django.db import models
from django.utils import timezone

class Post(models.Model):
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    published_at = models.DateTimeField(blank = True, null = True)

    def publish(self):
        self.published_at = timezone.now()
        self.save()

    def __str__(self):
        return self.title

 

 

데이터의 조회(Read)


 아래의 코드로 Post의 내용을 Read한다.

Post.objects.all()

 문제없이 실행됐다면 아래와 같은 결과를 확인할 수 있다.

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

 

 

데이터의 생성(Create)


 아래의 코드를 실행하면 Post의 새로운 데이터를 생성할 수 있다.

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)를 Read하면 아래와 같이 데이터가 잘 추가 되었다는 것을 확인할 수 있다.

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

 데이터 베이스 툴을 사용하여 확인해보 마찬가지로 잘 보존되고 있다는 것을 알 수 있다.

 

 

데이터의 갱신(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)


 아래의 코드로 위에서 작성했던 데이터를 삭제해보자.

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>]>

 

 

조회(Read) 조건


지금까지 데이터 베이스의 CRUD에 대해서 살펴보았다. 아래의 표는 데이터를 Read할 때 사용할 수 있는 일반적 검색 건에 대한 것이다. 

조회(Read) 조건

조회(Read) 조건 설명 사용법
__contains 조건의 텍스트가 포함된 데이터를 조회한다. Post.objects.filter(title__contains=’test’)
__icontains 조건의 텍스트가 대문자인지 소문자인지 구분하지 않고 포함되었다면 조회한다. Post.objects.filter(title__icontains=’this’)
__lt 작은 값의 경우 (It : 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 크거나 같은 값의 경우 (gte: 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’)
__month 해당 월로 조회 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]

 

 

 

정렬(sorting)


 아래의 코드를 사용하면 조회할 데이터를 오름차순과 내림차순으로 정렬하는 것이 가능하다.

● 오름차순

Post.objects.order_by(‘created_at’)

● 내림차순

Post.objects.order_by(‘-created_at’)

 

 

 

쉘(shell)을 종료


지금까지 Django의 쉘을 사용하여 간단한 Django의 ORM에 대해서 연습해보았다. 아래의 커맨드를 실시하면 Django의 쉘이 종료된다.

exit()

 

 

+) Django의 ORM쿼리에 관해 조금 더 심화적인 내용에 대해서 쉽게 소개해주신 포스팅이 있어서 공유합니다.

 

[Django] 반드시 알아야 할 5가지ORM 쿼리

비지니스 로직이 복잡한 상황에서 어떻게 ORM쿼리를 해야하는지 알아봅니다. 구글링으로 쉽게 찾기 어려운 ORM꿀팁을 가득 담았습니다!

medium.com


 참고자료

dev-yakuza.github.io/django/orm/

 

 
728x90