본문 바로가기
Python/Django

Django RDBMS 코드예시

by 좌우지간에 2025. 1. 10.

 

 

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 모델링은 데이터베이스를 설계하는 핵심적인 부분이며, 올바른 관계 설정을 통해 효율적이고 확장 가능한 앱을 개발할 수 있습니다.