Django에서 ORM(Object Relational Mapping)
데이터베이스 테이블을 파이썬 객체처럼 다룰 수 있게 해주는 기술
→ Python 쉘이나 view, script 안에서 실행할 수 있음
사전 준비하기
products 앱 생성, Product 모델 정의
python manage.py startapp products
# settings.py
INSTALLED_APPS = [
...,
# Local
"products",
...
]
# products/urls.py
from django.urls import path
urlpatterns = []
# urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("api/v1/articles/", include("articles.urls")),
path("api/v1/accounts/", include("accounts.urls")),
path("api/v1/products/", include("products.urls")),
]
# products/models.py
from django.db import models
class Product(models.Model):
CATEGORY_CHOICES = (
("F", "Fruit"),
("V", "Vegetable"),
("M", "Meat"),
("O", "Other"),
)
name = models.CharField(max_length=100)
price = models.PositiveIntegerField()
quantity = models.PositiveIntegerField()
category = models.CharField(max_length=1, choices=CATEGORY_CHOICES)
def __str__(self):
return self.name
price와 quantity는 양의 정수만 입력되도록 PositiveIntegerField 사용
category는 4가지 중 하나만 선택할 수 있도록 choices 설정 활용
마이그레이션
python manage.py makemigrations
python manage.py migrate
seed로 테스트 데이터 30개 생성
python manage.py seed products --number=30
django-seed를 사용하여 랜덤한 상품 데이터 생성
shell_plus 사용 준비
pip install django-extensions
# settings.py
INSTALLED_APPS = [
...,
# Third-party
"django_extensions",
...
]
python manage.py shell_plus
Django ORM을 이용하여 복합 조건, 집계 연산 처리 쿼리 사용하기
Q 객체: 복합 조건 처리
SQL의 WHERE 절에 해당하는 기능 활용 가능
OR 조건
가격이 15000 초과이거나 수량이 3000 미만인 상품 조회
Product.objects.filter(
Q(price__gt=15000) | Q(quantity__lt=3000)
)
AND 조건
가격이 10000 초과이고 수량이 2000 미만인 상품 조회
Product.objects.filter(
Q(price__gt=10000) & Q(quantity__lt=2000)
)
F 객체: 필드 값 참조
python 메모리로 값을 가져오지 않고 필요한 작업을 데이터베이스에서 수행 가능
기존 값 기반 업데이트
모든 상품의 가격을 1000원씩 인상
Product.objects.update(price=F('price') + 1000)


annotate(): 각 row에 계산 필드 추가
annotate == 주석을 달다
조회하는 쿼리셋 각각에 추가적인 정보(데이터)를 제공하는데 사용
총 가격 필드 추가
price × quantity를 계산하여 total_price 조회
products = Product.objects.annotate(
total_price=F('price') * F('quantity')
)
for product in products:
print(product.name, product.total_price)
aggregate(): 전체 데이터에 대한 집계
aggregate == 종합/집약하다
주로 집계 함수(Avg, Sum, Count 등)와 사용
평균 가격 구하기
Product.objects.aggregate(my_avg=Avg('price'))
카테고리별 상품 수 세기
잘못된 방식 (전체 개수만 나옴)
Product.objects.aggregate(Count('category'))
# {'category__count': 30}
올바른 방식: Group By 적용
Product.objects.values('category').annotate(
category_count=Count('category')
)
# [{'category': 'F', 'category_count': 6}, {'category': 'M', 'category_count': 11}, {'category': 'O', 'category_count': 11}, {'category': 'V', 'category_count': 2}]
Raw SQL 직접 사용하기
Raw() 활용
categories_count = Product.objects.raw(
'''
SELECT "id", "category", COUNT("category") AS "category_count"
FROM "products_product"
GROUP BY "category"
'''
)
for each in categories_count:
print(each.category, each.category_count)
"""
F 6
M 11
O 11
V 2
"""
DB 커넥션 사용
from django.db import connection
sql_query = '''
SELECT "category", COUNT("category") AS "category_count"
FROM "products_product"
GROUP BY "category"
'''
cursor = connection.cursor()
cursor.execute(sql_query)
result = cursor.fetchall()
print(result)
# [('F', 6), ('M', 11), ('O', 11), ('V', 2)]
Making queries | Django documentation
The web framework for perfectionists with deadlines.
docs.djangoproject.com
Query Expressions | Django documentation
The web framework for perfectionists with deadlines.
docs.djangoproject.com
QuerySet API reference | Django documentation
The web framework for perfectionists with deadlines.
docs.djangoproject.com
QuerySet API reference | Django documentation
The web framework for perfectionists with deadlines.
docs.djangoproject.com
'∟ Framework > ∟ DRF' 카테고리의 다른 글
Redis를 Django 캐시 백엔드로 설정하기 (1) | 2025.03.31 |
---|---|
ORM 최적화 (0) | 2025.03.31 |
Token Auth with JWT (0) | 2025.03.30 |
DRF Serializer 활용 (1) | 2025.03.30 |
DRF models with relationship CRUD API 구현 (0) | 2025.03.30 |