본문 바로가기
Programming/Django

[Python Django] 🔄 Django Circular & Lazy Relationships 완전 정리

by Mandy's 2025. 7. 23.

Django에서 모델을 정의하다 보면 종종 아래와 같은 상황을 마주하게 됩니다:

  • 두 모델이 서로를 참조하는 순환 관계 (circular relationship)
  • 하나의 모델이 자기 자신(self)과 관계를 맺는 경우
  • 다른 앱의 모델과 관계를 맺어야 할 때

이럴 땐 Lazy 관계 (지연 관계)를 통해 문제를 우회할 수 있습니다.
이번 포스트에서는 Django에서 자주 사용하는 Lazy 관계 예제를 3가지로 나눠서 설명합니다.


1️⃣ 서로를 참조하는 두 모델 (Circular Relationship)

class Product(models.Model):
    # ... other fields ...
    last_buyer = models.ForeignKey('User', on_delete=models.CASCADE)

class User(models.Model):
    # ... other fields ...
    created_products = models.ManyToManyField('Product')

🔍 문제 상황

  • Product는 User를 참조하고
  • 동시에 User도 Product를 참조해야 하는 구조입니다.
  • 파이썬에서는 한쪽 모델이 아직 정의되지 않았을 수 있어 직접 참조하면 에러가 납니다.

✅ 해결 방법

  • 문자열 형태로 모델명을 전달해 Django가 나중에 관계를 해석하도록 합니다.
  • 즉, 'User', 'Product'처럼 문자열로 모델명을 작성하면 순환 참조를 피할 수 있습니다.

2️⃣ 자기 자신과의 관계 (Self-referential)

class User(models.Model):
    # ... other fields ...
    friends = models.ManyToManyField('self')

🔍 사용 예시

  • 유저가 다른 유저들과 친구 관계를 맺는 SNS 구조
  • 트리/계층형 구조 (예: 댓글, 카테고리 등)

✅ 핵심

  • 'self'는 현재 모델 자신을 참조한다는 뜻입니다.
  • 다른 유저와의 관계를 정의할 때 매우 유용합니다.

3️⃣ 다른 앱의 모델 참조

class Review(models.Model):
    # ... other fields ...
    product = models.ForeignKey('store.Product', on_delete=models.CASCADE)

🔍 사용 예시

  • Review 모델이 store 앱의 Product 모델을 참조할 때
  • 또는 Django의 기본 모델(예: auth.User)이나 타 앱의 모델과 연결할 때

✅ 문법 요약

  • '앱이름.모델이름' 형태로 문자열을 넘기면 Django가 해당 모델을 찾아줍니다.
  • 예: 'auth.User', 'blog.Post', 'store.Product'

🧠 Lazy 관계가 필요한 이유

상황 Lazy 관계 필요 여부

두 모델이 서로 참조함 ✅ 필요 (순환 참조 방지)
자기 자신과 연결됨 ✅ 필요 ('self')
다른 앱의 모델 참조 ✅ 필요 ('앱.모델')
단일 방향 외래키만 있음 ❌ 일반 모델 참조로 가능

✅ 정리

패턴 예시

서로 참조 'User', 'Product'
자기 참조 'self'
다른 앱 모델 'store.Product', 'auth.User'

Lazy 관계는 단순히 편의가 아니라, 파이썬의 순서 제약과 앱 구조상 필수적인 기법입니다.


📌 참고 링크


궁금하신 분들은 댓글이나 이메일로 질문 주세요 :)
필요하시면 관련 예제 코드, ERD 이미지, 또는 계층 구조 모델링 포스트도 이어서 작성해보겠습니다!