장고 ORM 가이드: 모델의 모든 기능과 동작 살펴보기

정훈·2024년 12월 7일
0
post-thumbnail

이 글은 미디엄에 작성되어 있는 Django ORM Guide: Exploring All Model Methods and Operations을 원문으로 글을 작성하였습니다. 먼저 번역작업을 허락해준 denisa_dev에게 감사드립니다.
장고관련된 글을 많이 작성하시는 분이니 이 글을 읽으신 분들도 한번 들어가셔서 관심 가져볼 법한 글을 찾아서 읽어보세요!!

테이블 초기 상태

테이블 스키마

ERD

User 테이블

Category 테이블

Expense 테이블

Balance 테이블


1. 레코드 생성

new_user = User.objects.create(
				email="newuser@example.com", 
                first_name="New", 
                last_name="User", 
                is_active=True, 
                is_staff=False
           )

2. 단일 레코드 조회

user = User.objects.get(id=1)

3. 전체 레코드 조회

users = User.objects.all()

4. 조건에 속한 레코드 조회

active_users = User.objects.filter(is_active=True)

5. 조건에 속하지 않은 레코드 조회

non_active_users = User.objects.exclude(is_active=True)

6. 레코드 업데이트

user = User.objects.get(id=1)
user.first_name = "Jonathan"
user.save()

7. 조건에 속한 레코드 일괄 업데이트

User.objects.filter(is_active=True).update(is_staff=True)

8. 레코드 삭제

user = User.objects.get(id=3)
user.delete()

9. 레코드 논리 삭제(soft delete)

category = Category.objects.get(id=3)
category.deleted = True
category.save()

10. 데이터 집계

  • aggregate: Django에서 필드 전체의 합, 평균, 개수 등을 계산할 때 사용
from django.db.models import Sum

total_expenses = Expense.objects.aggregate(total=Sum('amount'))

11. 레코드 카운팅

total_users = User.objects.count()
print(total_users) # result: 2

12. 레코드 정렬

# 가격 기준으로 내림차순으로 정렬
expenses = Expense.objects.order_by('-amount')

13. 쿼리 결과 개수 제한

limited_expenses = Expense.objects.all()[:2]

14. Q class

from django.db.models import Q
filtered_users = User.objects.filter(Q(is_active=True) | Q(is_staff=True))

15. 외래키 조회 시 eager loading

expenses = Expense.objects.select_related('user').all()

16. 다대다 관계 조회 시 eager loading

categories = Category.objects.prefetch_related('expenses').all()

17. 중복 제거

distinct_emails = User.objects.values('email').distinct()

18. update_or_create

user, created = User.objects.update_or_create(
    email="user1@example.com",
    defaults={"first_name": "Johnny"}
)

19. get_or_create

user, created = User.objects.get_or_create(
    email="user1@example.com",
    defaults={"first_name": "Johnny"}
)

20. 조건에 해당하는 레코드 삭제

User.objects.filter(is_staff=True).delete()

21. 계산된 필드로 데이터에 별명 달기

from django.db.models import Count
categories = Category.objects.annotate(num_expenses=Count('expense'))
# expense 카운팅한 결과를 num_expenses라고 별명을 붙여준다.
# 이렇게 데이터를 불러올 수 있게 된다. categories[0].num_expenses

22. raw sql 작성 방법

users = User.objects.raw("SELECT * FROM app_user WHERE is_active = true")

23. 트랜잭션

from django.db import transaction

@transaction.atomic
def transfer_balance(user_id, amount):
    user = User.objects.select_for_update().get(id=user_id)
    user.balance.remaining_balance -= amount
    user.balance.save()

24. 여러 레코드 생성

Expense.objects.bulk_create([
    Expense(user_id=1, category_id=1, amount=20.00, description="Snack", date="2024-01-07"),
    Expense(user_id=2, category_id=2, amount=30.00, description="Internet", date="2024-01-07")
])

허락은 꽤 오래전에 맡았지만 이제야 완성하게되어 반성합니다. 처음에는 단순히 django orm 기능 관련해서 모음글을 작성해 놓으면 나중에 참고 할 때 좋게다고 생각해서 시작한 글이지만, 글을 작성하면서 의문이 생기는 점들을 하나하나 테스트 해보면서 새로 알게된 점이 생기는 글이였던것 같네요. 여러분들도 한번 하나하나 분리해서 테스트하면서 어떤 쿼리가 발생하는지 찾아 보면서 적용하는 시간을 가지셨으면 정말 좋을 것 같습니다!!

글을 읽어 주셔서 감사합니다. 마지막으로 번역을 허락해준 denisa_dev에게 다시 한번 감사드립니다.

profile
누군가에게 빛이 되길...

0개의 댓글