Django의 관계 필드

SMALL

1. OneToOneField

  • 1:1 관계를 표현
  • 예시 코드에서 Profile과 User 모델 간의 관계
  • 한 User는 하나의 Profile만 가질 수 있음
user = models.OneToOneField(
    to=settings.AUTH_USER_MODEL,  # 연결할 모델
    on_delete=models.CASCADE      # 참조하는 객체가 삭제될 때의 동작
)

 

 

2. ForeignKey

  • 1:N 관계를 표현
  • 예시 코드에서 Post와 User 모델 간의 관계
  • 한 User는 여러 개의 Post를 작성할 수 있음
author = models.ForeignKey(
    settings.AUTH_USER_MODEL,     # 참조할 모델
    on_delete=models.CASCADE      # 삭제 시 동작
)

 

 

3. ManyToManyField

  • N:M 관계를 표현
  • 예시 코드에서 Post와 Tag 모델 간의 관계
  • 하나의 Post는 여러 Tag를 가질 수 있고, 하나의 Tag는 여러 Post에 속할 수 있음
tag_set = models.ManyToManyField(
    'Tag',                       # 연결할 모델
    blank=True                   # 필수 여부
)

 

 


 

from django.conf import settings  # Django 설정 가져오기
from django.contrib.auth.models import AbstractUser  # Django 기본 사용자 모델
from django.db import models  # Django 모델 기능

# User 모델 - Django 기본 사용자 모델을 확장
class User(AbstractUser):
    # 사용자 추가 정보 필드
    bio = models.TextField()  # 자기소개 텍스트 필드
    
    def __str__(self):
        # 사용자 객체를 문자열로 표현할 때 사용자명 반환
        return self.username

# Profile 모델 - 사용자와 1:1 관계를 가지는 프로필
class Profile(models.Model):
    # OneToOneField로 User 모델과 1:1 관계 설정
    user = models.OneToOneField(
        to=settings.AUTH_USER_MODEL,      # AUTH_USER_MODEL 설정에 지정된 사용자 모델과 연결
        on_delete=models.CASCADE,         # 연결된 User가 삭제되면 Profile도 함께 삭제
        related_name='profile'            # User 모델에서 Profile을 참조할 때 사용할 이름
    )
    address = models.CharField(max_length=50)  # 주소 저장 필드
    zipcode = models.CharField(max_length=6)   # 우편번호 저장 필드
    
    def __str__(self):
        # 프로필 객체를 문자열로 표현할 때 "사용자명's profile" 형태로 반환
        return f"{self.user.username}'s profile"

# Tag 모델 - 게시글에 붙일 수 있는 태그
class Tag(models.Model):
    # 태그 이름 필드 (unique=True로 중복 태그명 방지)
    name = models.CharField(max_length=44, unique=True)
    
    def __str__(self):
        # 태그 객체를 문자열로 표현할 때 태그명 반환
        return self.name

# Post 모델 - 게시글 정보를 저장
class Post(models.Model):
    # ForeignKey로 User 모델과 1:N 관계 설정 (한 사용자가 여러 게시글 작성 가능)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,         # 게시글 작성자
        on_delete=models.CASCADE,         # 작성자가 삭제되면 게시글도 함께 삭제
        related_name='posts'              # User 모델에서 작성한 게시글 목록 참조시 사용할 이름
    )
    message = models.TextField()          # 게시글 내용
    created_at = models.DateTimeField(auto_now_add=True)  # 생성 시간 (자동 저장)
    updated_at = models.DateTimeField(auto_now=True)      # 수정 시간 (자동 업데이트)
    
    # ManyToManyField로 Tag 모델과 N:M 관계 설정
    tag_set = models.ManyToManyField(
        'Tag',                           # 연결할 모델
        blank=True,                      # 태그는 필수가 아님
        related_name='posts'             # Tag 모델에서 해당 태그가 붙은 게시글 목록 참조시 사용할 이름
    )
    
    class Meta:
        ordering = ['-created_at']       # 게시글을 생성 시간 역순으로 정렬
    
    def __str__(self):
        # 게시글 객체를 문자열로 표현할 때 "작성자명's post: 게시글 내용 일부" 형태로 반환
        return f"{self.author.username}'s post: {self.message[:20]}"
        
        
# 사용자의 프로필 조회
user.profile

# 사용자가 작성한 모든 포스트 조회
user.posts.all()

# 특정 태그가 달린 모든 포스트 조회
tag.posts.all()

# 포스트의 작성자 조회
post.author

# 포스트의 모든 태그 조회
post.tag_set.all()

 

 

 

 

 

 

 

 

 

 

LIST