IT/Django

Django에서 사용하는 다양한 파일구조

mmww 2024. 10. 11. 09:12

Django 로고

Django는 프로젝트를 보다 구조화하고 유지보수하기 쉽게 만드는 다양한 파일 구조를 제공합니다. 일반적으로 사용되는 models.py, views.py, urls.py, admin.py, forms.py, serializers.py 외에도 프로젝트나 앱의 규모가 커짐에 따라 각 기능을 세분화한 파일들이 많이 사용됩니다. 이번 글에서는 추가 파일들, 즉 managers.py, signals.py, permissions.py, tasks.py, contexts.py에 대해 알아보겠습니다. 이들 파일은 주로 대규모 웹 애플리케이션을 개발할 때 사용되며, 더 나은 코드 관리를 위해 각 기능에 맞는 역할을 수행합니다.


1. managers.py - 커스텀 쿼리셋 로직 정의

managers.py는 Django 모델에 대한 커스텀 매니저와 쿼리셋 로직을 정의하는 파일입니다. 기본적으로 Django는 objects라는 매니저를 통해 데이터베이스와 상호작용하는 쿼리를 처리합니다. 하지만 특정 비즈니스 로직에 맞는 커스텀 쿼리셋을 추가하고 싶을 때 이 파일을 사용하여 쿼리 로직을 모듈화할 수 있습니다.

주요 사용 이유

  • 복잡한 쿼리를 캡슐화: 여러 곳에서 사용하는 복잡한 쿼리를 함수로 정의해 재사용할 수 있습니다.
  • 모델별 특화된 로직 구현: 모델과 관련된 특화된 쿼리 로직을 정의해 코드 중복을 줄일 수 있습니다.

상세 예시

from django.db import models

# 커스텀 매니저 정의
class PostManager(models.Manager):
    def published(self):
        # 게시된 글만 필터링
        return self.filter(status='published')

    def recent_posts(self):
        # 최근 게시물 5개 가져오기
        return self.filter(status='published').order_by('-created_at')[:5]

# 모델에 매니저 적용
class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    status = models.CharField(max_length=10)
    created_at = models.DateTimeField(auto_now_add=True)

    # 커스텀 매니저 등록
    objects = PostManager()

이 예시는 게시된 게시물만 필터링하는 published 메서드와 최근 게시물을 가져오는 recent_posts 메서드를 제공하여 코드를 간결하고 직관적으로 사용할 수 있게 해줍니다.


2. signals.py - 이벤트 기반 동작 처리

signals.py는 Django에서 특정 이벤트가 발생할 때 자동으로 특정 작업을 실행하는 '신호'를 정의하는 파일입니다. Django의 신호(signals)는 예를 들어 모델 인스턴스가 저장되거나 삭제될 때, 혹은 사용자 로그인 시 특정 동작을 수행하는 데 활용됩니다.

주요 사용 이유

  • 모델 저장 후 추가 동작: 모델 인스턴스가 저장된 후 이메일 알림을 보내거나 로그를 남기는 등 후처리를 수행할 수 있습니다.
  • 이벤트 기반 프로세스: 특정 이벤트를 기준으로 시스템의 자동화 작업을 수행할 수 있습니다.

상세 예시

from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import UserProfile

# 사용자 프로필이 생성되면, 환영 이메일 전송
@receiver(post_save, sender=UserProfile)
def send_welcome_email(sender, instance, created, **kwargs):
    if created:
        # 이메일 전송 로직
        print(f'환영 이메일을 {instance.user.email}로 보냈습니다.')

위 예시는 새로운 UserProfile 인스턴스가 생성될 때마다 환영 이메일을 전송하는 신호를 설정한 것입니다. 이처럼 signals.py를 통해 다양한 시스템 이벤트에 대한 후처리 작업을 자동화할 수 있습니다.


3. permissions.py - 접근 제어 설정

permissions.py는 Django REST Framework(DRF)에서 API 엔드포인트에 대한 접근 권한을 정의하는 파일입니다. 이 파일은 사용자의 권한을 제어하거나 특정 조건에 따라 접근을 허용 또는 차단하는 데 사용됩니다. 권한은 주로 보안이 중요한 웹 애플리케이션에서 중요한 역할을 합니다.

주요 사용 이유

  • 사용자 권한 관리: 사용자의 권한에 따라 API 접근을 제한할 수 있습니다.
  • API 보안 강화: 민감한 데이터를 다루는 API의 보안을 높이기 위해 조건부 접근 허용을 설정할 수 있습니다.

상세 예시

from rest_framework import permissions

# 오브젝트 소유자만 수정할 수 있는 커스텀 권한 클래스
class IsOwnerOrReadOnly(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        # GET, HEAD, OPTIONS 메서드는 모두 허용
        if request.method in permissions.SAFE_METHODS:
            return True
        # 오브젝트의 소유자만 수정 가능
        return obj.owner == request.user

이 예시는 사용자 소유의 객체에만 수정 권한을 부여하고, 읽기 권한은 모든 사용자에게 허용하는 커스텀 권한 클래스를 정의합니다.


4. tasks.py - 비동기 작업 처리

tasks.py는 주로 Django에서 비동기 작업을 처리하기 위한 파일입니다. Celery와 같은 작업 큐(Task Queue) 라이브러리와 함께 사용하여 긴 시간 소요되는 작업(예: 이메일 전송, 데이터 처리)을 비동기로 처리할 수 있습니다. 이를 통해 웹 애플리케이션의 성능과 사용자 경험을 향상시킬 수 있습니다.

주요 사용 이유

  • 백그라운드 작업 처리: 시간이 오래 걸리는 작업을 비동기적으로 처리하여 웹 애플리케이션의 응답 속도를 높입니다.
  • 스케줄링 작업: 주기적인 작업을 자동으로 실행하여 서버의 성능을 최적화할 수 있습니다.

상세 예시

from celery import shared_task

# 비동기 이메일 전송 작업
@shared_task
def send_email_task(email_address):
    # 이메일 전송 로직
    print(f'이메일을 {email_address}로 전송했습니다.')

# 매일 자정마다 실행될 주기적 작업
@shared_task
def daily_report():
    # 리포트 생성 로직
    print('일일 리포트를 생성했습니다.')

이처럼 tasks.py는 장시간이 소요되거나 주기적으로 반복되어야 하는 작업을 처리하는 데 유용합니다. Celery와 함께 활용하면 다양한 백그라운드 작업을 효과적으로 관리할 수 있습니다.


5. contexts.py - 전역 컨텍스트 데이터 정의

contexts.py는 뷰와 템플릿 사이에 공유되는 데이터를 정의하는 파일로, 전역적으로 사용되는 데이터를 템플릿에 전달할 수 있습니다. 이를 통해 중복되는 코드를 줄이고, 다양한 뷰에서 일관성 있게 데이터를 제공할 수 있습니다.

주요 사용 이유

  • 템플릿에 전역 데이터 제공: 여러 뷰에서 공통으로 사용되는 데이터를 한 곳에서 정의하고, 이를 전역적으로 사용할 수 있습니다.
  • 코드 재사용성 증가: 중복되는 컨텍스트 데이터를 한 번에 관리할 수 있습니다.

상세 예시

# contexts.py
def global_context(request):
    return {
        'site_name': 'My Awesome Site',
        'user_notifications': request.user.notifications.all() if request.user.is_authenticated else []
    }

# settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'OPTIONS': {
            'context_processors': [
                # 다른 기본 제공 컨텍스트 프로세서들...
                'myapp.contexts.global_context',  # 커스텀 컨텍스트 프로세서 등록
            ],
        },
    },
]

위의 예시는 웹사이트 이름(site_name)과 로그인된 사용자의 알림 데이터를 전역적으로 템플릿에 전달하는 예입니다. 여러 뷰에서 반복적으로 사용할 데이터를 일관되게 관리할 수 있습니다.


더 알아보기

  • projectmanagers.py앱 내 managers.py의 차이점: projectmanagers.py는 프로젝트 전반에 걸친 공통 쿼리 로직을 관리하며, 여러 앱에서 공유됩니다. 반면 앱 내 managers.py는 해당 앱에 종속된 커스텀 쿼리셋과 매니저를 정의합니다. 따라서 범용성과 구체성이 주요 차이점입니다.
  • managers.pyservices.py의 차이점: managers.py는 주로 데이터베이스와 관련된 쿼리 로직을 정의하고, 모델과 밀접하게 연관되어 있습니다. 반면 services.py비즈니스 로직을 처리하는데, 데이터베이스뿐만 아니라 외부 API 호출, 파일 처리 등
  • 다양한 작업을 포함할 수 있습니다. 즉, managers.py데이터 접근에 중점을 두고, services.py비즈니스 로직에 중점을 둡니다.

결론

Django에서는 파일을 역할에 따라 세분화하여 기능을 모듈화할 수 있습니다. managers.py, signals.py, permissions.py, tasks.py, contexts.py는 각각의 역할에 맞춰 비즈니스 로직을 캡슐화하고, 유지보수성을 높이며, 성능 최적화에 기여합니다. 특히 대규모 프로젝트나 API 중심의 서비스 개발 시 이들 파일을 적절히 활용하면 코드의 구조가 더 명확해지고, 재사용성도 높아집니다.

'IT > Django' 카테고리의 다른 글

Django 에서 토큰 기반 인증 과 JWT 기반 인증  (1) 2024.09.27