Django ORM을 이용한 데이터 조회는 Django의 가장 강력한 기능 중 하나입니다. QuerySet은 Django 모델로부터 데이터를 효율적으로 가져오는 기본 도구이며, 이 도구를 활용하면 복잡한 데이터 조회도 손쉽게 처리할 수 있습니다. 이번 글에서는 QuerySet이 무엇인지, 어떻게 활용할 수 있는지, 그리고 데이터 조회에 유용한 다양한 기능에 대해 살펴보겠습니다.


1. QuerySet이란 무엇인가?

QuerySetDjango ORM에서 데이터베이스로부터 데이터를 가져오거나 조작할 때 사용하는 객체의 모음입니다. 쉽게 말해, QuerySet은 데이터베이스 질의(Query)를 실행한 결과의 집합이라고 할 수 있습니다. QuerySet을 사용하면 모델 객체들을 가져오고, 필터링하고, 조작할 수 있습니다.

QuerySet은 데이터베이스와의 상호작용을 캡슐화하여 개발자가 SQL을 직접 작성하지 않고도 직관적인 Python 코드로 데이터를 조회하거나 조작할 수 있게 도와줍니다.

Django QuerySet infographic

QuerySet으로 할 수 있는 것

  • 데이터 조회: 데이터베이스에 저장된 레코드를 다양한 조건으로 조회할 수 있습니다.
  • 필터링: 원하는 데이터만 골라낼 수 있도록 여러 조건을 적용할 수 있습니다.
  • 정렬 및 슬라이싱: 데이터를 원하는 순서대로 정렬하거나 특정 범위의 데이터를 가져올 수 있습니다.

2. 기본 조회 메서드의 종류와 활용 예시

Django ORM에서는 다양한 기본 조회 메서드를 제공합니다. 이 메서드들은 데이터를 쉽게 조회하고 필터링하는 데 매우 유용합니다.

2.1 all()

모델의 모든 데이터를 가져오고 싶을 때 사용하는 메서드입니다.

from myapp.models import Post

posts = Post.objects.all()
  • Post.objects.all()은 Post 모델에 저장된 모든 객체를 가져옵니다.

2.2 filter()

특정 조건에 맞는 객체들만 가져오고 싶을 때 사용합니다.

published_posts = Post.objects.filter(status='published')
  • filter()는 조건에 맞는 객체들을 조회하며, 반환 결과는 QuerySet입니다.

2.3 exclude()

특정 조건을 제외한 객체들을 가져올 때 사용합니다.

draft_posts = Post.objects.exclude(status='published')
  • exclude()filter()와 반대로 조건에 맞지 않는 객체들을 조회합니다.

2.4 get()

특정 조건에 맞는 단일 객체를 가져올 때 사용합니다. 단, 조건에 맞는 객체가 없거나 두 개 이상인 경우 오류가 발생합니다.

post = Post.objects.get(id=1)
  • get()은 정확히 하나의 객체만 조회할 때 사용되며, 결과가 없거나 여러 개인 경우에는 DoesNotExist 또는 MultipleObjectsReturned 예외가 발생합니다.

3. ORM의 연산자와 필터링

QuerySet은 다양한 연산자를 사용하여 복잡한 필터 조건을 처리할 수 있습니다. 이러한 연산자를 사용하면 매우 세부적인 조건으로 데이터를 필터링할 수 있습니다.

3.1 exact

정확히 일치하는 값을 찾고자 할 때 사용합니다.

post = Post.objects.filter(title__exact='My First Post')
  • title__exact는 제목이 정확히 'My First Post'인 객체를 필터링합니다.

3.2 icontains

대소문자를 구분하지 않고 부분 문자열을 포함하는지를 검색할 때 사용합니다.

posts = Post.objects.filter(title__icontains='django')
  • title__icontains는 제목에 'django'가 포함된 모든 게시물을 조회합니다.

3.3 gt, lt (크다, 작다)

숫자 또는 날짜 값에서 보다 크거나 작은 조건을 설정할 때 사용합니다.

recent_posts = Post.objects.filter(publish_date__gt='2024-01-01')
  • publish_date__gt2024-01-01 이후에 게시된 포스트들을 필터링합니다. gtgreater than, ltless than을 의미합니다.

이 외에도 startswith, endswith, in 등의 다양한 연산자를 사용할 수 있어 다양한 필터링 조건을 간단히 구현할 수 있습니다.


4. 역참조: 외래 키로 연결된 모델 간의 관계 조회

Django ORM에서 역참조외래 키(Foreign Key)를 사용해 연결된 모델 간의 관계를 통해 데이터를 조회하는 방식입니다. 역참조를 활용하면 관계형 데이터베이스에서 부모와 자식 간의 관계를 편리하게 조회할 수 있습니다.


4.1 related_name을 사용한 역참조

외래 키를 정의할 때 related_name 옵션을 사용하면, 역참조 시 더 읽기 쉬운 이름을 사용할 수 있습니다.

예제
class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
    text = models.TextField()
사용법
post = Post.objects.get(id=1)
comments = post.comments.all()
  • post.comments.all()을 사용하면 해당 게시물에 달린 모든 댓글을 가져올 수 있습니다. related_name을 설정하지 않았다면 기본적으로 comment_set이라는 이름을 사용하게 됩니다.

결론

Django ORM의 QuerySet은 데이터베이스와 상호작용하기 위한 강력한 도구로, 다양한 메서드와 연산자를 통해 원하는 데이터를 효율적으로 조회하고 조작할 수 있습니다. 이번 글에서는 기본적인 QuerySet 사용법과 함께, 데이터를 필터링하고 역참조하는 방법을 살펴보았습니다.

위에서 소개한 부분은 ORM의 조회 기능의 아주 기초적인 입문에 불과합니다. 실제 Django의 QuerySet은 더욱 다양하고 강력한 메서드들을 가지고 있으며 이 메서드들을 조합하여 사용하여 데이터를 조회할 수 있습니다. 향후 QuerySet의 다양한 메서드들을 하나하나 소개하고 분석하는 포스트를 작성해보도록 하겠습니다.

다음 편에서는 QuerySet의 성능 최적화지연 평가(lazy evaluation)의 개념을 다루어, 더 나은 성능을 위한 데이터 접근 방법에 대해 알아보겠습니다. 기대해주세요!