🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Django 실무 활용 팁 고급 가이드 - 슬라이드 1/13
A

AI Generated

2025. 11. 2. · 8 Views

Django 실무 활용 팁 고급 가이드

Django 프로젝트에서 실무에 바로 적용할 수 있는 고급 활용 팁을 소개합니다. 성능 최적화, 보안, 코드 품질 향상을 위한 실전 예제를 다룹니다.


카테고리:Python
언어:Python
메인 태그:#Django
서브 태그:
#QuerySet#Middleware#Signals#ORM

들어가며

이 글에서는 Django 실무 활용 팁 고급 가이드에 대해 상세히 알아보겠습니다. 총 12가지 주요 개념을 다루며, 각각의 개념에 대한 설명과 실제 코드 예제를 함께 제공합니다.

목차

  1. select_related와_prefetch_related
  2. 커스텀_Manager로_쿼리_재사용
  3. F()_표현식으로_경쟁_조건_방지
  4. Annotate와_Aggregate로_집계_쿼리
  5. 커스텀_Middleware로_공통_로직_처리
  6. Signals_대신_Model_메서드_사용
  7. Cached_Property로_성능_개선
  8. Bulk_Create로_대량_INSERT_최적화
  9. 트랜잭션_원자성_보장
  10. Q_객체로_복잡한_쿼리_조합
  11. Custom_Template_Tags로_재사용_로직
  12. Context_Manager로_안전한_리소스_관리

개요

N+1 쿼리 문제를 해결하기 위한 Django ORM의 핵심 최적화 기법입니다.

코드 예제

# Bad: N+1 queries
for book in Book.objects.all():
    print(book.author.name)

# Good: 단일 JOIN 쿼리
books = Book.objects.select_related('author')
for book in books:
    print(book.author.name)

설명

select_related는 ForeignKey 관계를 JOIN으로 한 번에 가져오고, prefetch_related는 ManyToMany 관계를 별도 쿼리로 최적화합니다.


2. 커스텀 Manager로 쿼리 재사용

개요

자주 사용하는 쿼리를 Manager로 캡슐화하여 코드 중복을 줄이고 유지보수성을 높입니다.

코드 예제

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='published')

class Article(models.Model):
    objects = models.Manager()
    published = PublishedManager()
    status = models.CharField(max_length=20)

설명

Article.published.all()로 간단하게 게시된 글만 조회할 수 있으며, 쿼리 로직이 모델에 집중됩니다.


3. F() 표현식으로 경쟁 조건 방지

개요

데이터베이스 레벨에서 원자적 업데이트를 수행하여 동시성 문제를 해결합니다.

코드 예제

from django.db.models import F

# Bad: 경쟁 조건 발생 가능
product.stock -= 1
product.save()

# Good: DB 레벨에서 원자적 업데이트
Product.objects.filter(id=product_id).update(stock=F('stock') - 1)

설명

F() 표현식은 Python이 아닌 데이터베이스에서 값을 참조하므로 동시 요청에도 안전합니다.


4. Annotate와 Aggregate로 집계 쿼리

개요

복잡한 집계 연산을 ORM으로 효율적으로 처리하는 방법입니다.

코드 예제

from django.db.models import Count, Avg

# 저자별 책 개수와 평균 평점
authors = Author.objects.annotate(
    book_count=Count('books'),
    avg_rating=Avg('books__rating')
).filter(book_count__gt=5)

설명

annotate는 각 객체에 계산 필드를 추가하고, aggregate는 전체 쿼리셋의 집계 값을 반환합니다.


5. 커스텀 Middleware로 공통 로직 처리

개요

모든 요청/응답에 대한 공통 처리를 중앙화하여 코드 중복을 제거합니다.

코드 예제

class RequestTimingMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        start_time = time.time()
        response = self.get_response(request)
        duration = time.time() - start_time
        response['X-Request-Duration'] = str(duration)
        return response

설명

미들웨어는 요청 전후로 실행되며, 로깅, 인증, 성능 모니터링 등에 활용됩니다.


6. Signals 대신 Model 메서드 사용

개요

과도한 Signal 사용은 디버깅을 어렵게 만들므로, 명시적인 모델 메서드를 우선합니다.

코드 예제

class Order(models.Model):
    def complete(self):
        self.status = 'completed'
        self.save()
        # 명시적으로 후속 작업 실행
        self.send_confirmation_email()
        self.update_inventory()
        return self

설명

Signal은 암묵적이고 추적이 어려우므로, 비즈니스 로직은 명시적인 메서드로 구현하는 것이 유지보수에 유리합니다.


7. Cached Property로 성능 개선

개요

계산 비용이 높은 프로퍼티를 캐싱하여 반복 호출 시 성능을 향상시킵니다.

코드 예제

from django.utils.functional import cached_property

class User(models.Model):
    @cached_property
    def total_orders_value(self):
        return self.orders.aggregate(
            total=Sum('amount')
        )['total'] or 0

설명

cached_property는 첫 접근 시 계산 후 결과를 캐싱하여, 같은 인스턴스에서 반복 호출 시 재계산하지 않습니다.


8. Bulk Create로 대량 INSERT 최적화

개요

수천 개의 레코드를 삽입할 때 쿼리 수를 대폭 줄이는 방법입니다.

코드 예제

# Bad: 1000번의 INSERT
for i in range(1000):
    Product.objects.create(name=f'Product {i}')

# Good: 단일 INSERT
products = [Product(name=f'Product {i}') for i in range(1000)]
Product.objects.bulk_create(products, batch_size=100)

설명

bulk_create는 여러 객체를 한 번의 쿼리로 삽입하며, batch_size로 메모리 사용을 조절할 수 있습니다.


9. 트랜잭션 원자성 보장

개요

여러 DB 작업을 하나의 원자적 단위로 묶어 데이터 일관성을 보장합니다.

코드 예제

from django.db import transaction

@transaction.atomic
def transfer_money(from_account, to_account, amount):
    from_account.balance -= amount
    from_account.save()
    to_account.balance += amount
    to_account.save()

설명

atomic 데코레이터는 함수 내 모든 DB 작업을 하나의 트랜잭션으로 처리하여, 오류 시 자동 롤백됩니다.


10. Q 객체로 복잡한 쿼리 조합

개요

OR, AND, NOT 조건을 조합하여 복잡한 검색 로직을 구현합니다.

코드 예제

from django.db.models import Q

# (status='published' AND category='tech') OR author='admin'
articles = Article.objects.filter(
    Q(status='published', category='tech') | Q(author='admin')
)

설명

Q 객체는 &(AND), |(OR), ~(NOT) 연산자로 조합 가능하며, 동적 쿼리 빌딩에 필수적입니다.


11. Custom Template Tags로 재사용 로직

개요

템플릿에서 반복되는 로직을 커스텀 태그로 추출하여 재사용성을 높입니다.

코드 예제

from django import template

register = template.Library()

@register.simple_tag
def format_price(amount, currency='USD'):
    return f'{currency} {amount:,.2f}'

# 템플릿: {% format_price product.price 'KRW' %}

설명

simple_tag는 Python 함수를 템플릿 태그로 변환하며, 복잡한 포맷팅이나 계산을 뷰에서 분리할 수 있습니다.


12. Context Manager로 안전한 리소스 관리

개요

데이터베이스 연결이나 파일 처리 시 리소스 누수를 방지합니다.

코드 예제

from django.db import connection

def execute_raw_sql(query):
    with connection.cursor() as cursor:
        cursor.execute(query)
        return cursor.fetchall()
    # cursor는 자동으로 닫힘

설명

with 문은 블록 종료 시 자동으로 리소스를 정리하여, 예외 발생 시에도 안전하게 연결을 닫습니다.


마치며

이번 글에서는 Django 실무 활용 팁 고급 가이드에 대해 알아보았습니다. 총 12가지 개념을 다루었으며, 각각의 사용법과 예제를 살펴보았습니다.

관련 태그

#Django #QuerySet #Middleware #Signals #ORM

#Django#QuerySet#Middleware#Signals#ORM#Python

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.