Django 모델링: 1:1, 1:N, N:M 관계 코드 예시
Django에서 데이터베이스 모델링은 핵심적인 부분입니다. 데이터를 어떻게 구조화하고 저장할지 결정하며, 이는 앱의 기능과 성능에 큰 영향을 미칩니다. 이번 글에서는 Django 모델에서 가장 흔하게 사용되는 세 가지 관계(1:1, 1:N, N:M)를 코드 예시와 함께 자세히 알아보겠습니다.
1. 1:1 관계 (One-to-One Relationship)
1:1 관계는 두 테이블의 레코드가 정확히 하나씩 연결되는 관계입니다. 예를 들어, 사용자(User)와 사용자 프로필(UserProfile)이 1:1 관계일 때, 각 사용자는 하나의 프로필만을 가질 수 있으며, 각 프로필은 한 명의 사용자에게만 속하게 됩니다.
코드 예시:
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
# AbstractUser를 상속받아 User 모델 생성
class User(AbstractUser):
def __str__(self):
return self.username
# User의 포인트 정보를 저장하는 UserPoint 모델
class UserPoint(models.Model):
# OneToOneField를 사용하여 User 모델과 1:1 관계 설정
user = models.OneToOneField(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="userpoints")
# 포인트는 양수만 허용
points = models.PositiveIntegerField(default=0)
def __str__(self):
return f"{self.user.username} : {self.points}점"
코드 설명:
User모델: Django의 기본 사용자 모델인AbstractUser를 상속받아 사용자 테이블을 생성합니다.UserPoint모델:user = models.OneToOneField(...):OneToOneField를 사용하여User모델과 1:1 관계를 설정합니다.settings.AUTH_USER_MODEL: settings.py에 설정된 활성화된 유저 모델을 참조합니다.on_delete=models.CASCADE: 연결된 User가 삭제될 경우, 해당 UserPoint도 함께 삭제됩니다.related_name="userpoints": User 모델에서 UserPoint에 접근할 때 사용할 이름 (예:user.userpoints).
points = models.PositiveIntegerField(default=0): 사용자의 포인트를 저장하는 필드입니다. 0 이상의 정수만 허용합니다.
개념 설명:
OneToOneField: Django에서 1:1 관계를 정의하는 필드입니다.on_delete: 연결된 객체가 삭제될 때 어떻게 할지 지정합니다.models.CASCADE는 연쇄 삭제를 의미합니다.related_name: 역참조를 위한 이름입니다. User 모델 인스턴스에서user.userpoints와 같이related_name을 통해 UserPoint를 가져올 수 있습니다.
활용 예시:
- 사용자 프로필 정보 (추가적인 사용자 정보)
- 사용자 설정
- 사용자별 고유한 통계 정보
2. 1:N 관계 (One-to-Many Relationship)
1:N 관계는 하나의 테이블 레코드가 여러 개의 다른 테이블 레코드와 연결되는 관계입니다. 예를 들어, 한 명의 사용자(User)는 여러 개의 게시글(Post)을 작성할 수 있습니다.
코드 예시:
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
# AbstractUser를 상속받아 User 모델 생성
class User(AbstractUser):
def __str__(self):
return self.username
# 게시글 정보를 저장하는 Post 모델
class Post(models.Model):
title = models.CharField(max_length=140)
content = models.TextField()
# ForeignKey를 사용하여 User 모델과 1:N 관계 설정
author = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="posts")
def __str__(self):
return self.title
코드 설명:
Post모델:author = models.ForeignKey(...):ForeignKey를 사용하여User모델과 1:N 관계를 설정합니다.settings.AUTH_USER_MODEL: settings.py에 설정된 활성화된 유저 모델을 참조합니다.on_delete=models.CASCADE: 연결된 User가 삭제될 경우, 해당 Post도 함께 삭제됩니다.related_name="posts": User 모델에서 Post에 접근할 때 사용할 이름 (예:user.posts.all()).
개념 설명:
ForeignKey: Django에서 1:N 관계를 정의하는 필드입니다. 외래키는 다른 테이블의 기본 키를 참조합니다.related_name을 사용하면 유저 객체에서 해당 유저가 작성한 모든 Post 객체에 쉽게 접근할 수 있습니다.
활용 예시:
- 블로그 게시글과 사용자
- 주문과 고객
- 댓글과 게시글
3. N:M 관계 (Many-to-Many Relationship)
N:M 관계는 여러 개의 테이블 레코드가 여러 개의 다른 테이블 레코드와 연결되는 관계입니다. 예를 들어, 한 명의 사용자(User)는 여러 개의 게시글(Post)에 좋아요를 누를 수 있고, 한 개의 게시글은 여러 명의 사용자에게 좋아요를 받을 수 있습니다.
코드 예시:
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.conf import settings
# AbstractUser를 상속받아 User 모델 생성
class User(AbstractUser):
def __str__(self):
return self.username
# 게시글 정보를 저장하는 Post 모델
class Post(models.Model):
title = models.CharField(max_length=140)
content = models.TextField()
# ForeignKey를 사용하여 User 모델과 1:N 관계 설정
author = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="posts")
# ManyToManyField를 사용하여 User 모델과 N:M 관계 설정
likes = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name="liked_posts", blank=True)
# 성능 및 효율을 생각할때 좋아요 숫자만 갖고있는 likes_count 같은 필드도 만들어주면 더 좋긴함.
# ex) likes_count = models.IntegerField(default=0)
# 이러면 나중에 좋아요 순 게시글 같은거 할때 좀더 좋음.
def __str__(self):
return self.title
코드 설명:
Post모델:likes = models.ManyToManyField(...):ManyToManyField를 사용하여User모델과 N:M 관계를 설정합니다.related_name="liked_posts": User 모델에서 좋아요를 누른 게시글에 접근할 때 사용할 이름 (예:user.liked_posts.all()).blank=True: 좋아요를 안눌러도 게시글을 작성할 수 있도록 설정합니다.
개념 설명:
ManyToManyField: Django에서 N:M 관계를 정의하는 필드입니다. Django는 자동으로 중간 테이블을 생성하여 관계를 관리합니다.
활용 예시:
- 게시글 좋아요와 사용자
- 상품과 카테고리
- 사용자와 그룹
- 학생과 수업
추가적으로 고려할 점
- 성능: N:M 관계에서 좋아요 갯수와 같은 정보를 자주 사용한다면, 별도의
IntegerField필드를 추가하여 성능을 최적화할 수 있습니다. through모델: N:M 관계에서 중간 테이블에 추가적인 필드를 저장해야 한다면through옵션을 사용하여 중간 테이블을 명시적으로 정의할 수 있습니다.- ORM 성능 개선 : Django ORM은 강력하지만, 대량의 데이터를 다룰때는 때때로 성능 문제가 발생할 수 있습니다.
select_related(),prefetch_related()와 같은 방법을 사용하여 성능을 개선할 수 있습니다.
마무리
이번 글에서는 Django 모델에서 가장 중요한 관계인 1:1, 1:N, N:M 관계를 코드 예시와 함께 자세히 알아보았습니다. Django 모델링은 데이터베이스를 설계하는 핵심적인 부분이며, 올바른 관계 설정을 통해 효율적이고 확장 가능한 앱을 개발할 수 있습니다.
'Python > Django' 카테고리의 다른 글
| Django form활용 유효성검사 (1) | 2025.01.14 |
|---|---|
| Django 객체 추상화(모델 클래스 상속) (1) | 2025.01.13 |
| 관계형 데이터베이스 보충 (3) | 2025.01.09 |
| Django AUTH USER 사용자 모델 (2) | 2025.01.08 |
| Django 워크플로우 정리 (CRUD, 로그인 기능까지) (0) | 2025.01.08 |