Model 설계에 있어서 Relationship은 정말 중요합니다.

관계를 설정해주는 방법은 3가지가 있습니다.


1. ForeignKey

ForeignKey는 one to many 관계를 의미합니다.
게시물과 댓글의 경우를 떠올리면 됩니다.

한 게시물에 여러 댓글이 달릴 수 있습니다.

class Post(models.Model):
  # 생략
class Comment(models.Model):
  post = models.ForeignKey(Post, on_delete=models.CASCADE)

위처럼 many에 해당하는 클래스에서 관계를 설정합니다.

1-1. on_delete

on_delete설정은 one에 해당하는 데이터가 삭제 되었을 시, many에 해당하는 데이터를 어떻게 처리할 지 결정합니다.

  • CASCADE: one과 연결되어 있던 모든 many의 데이터들을 삭제합니다.
  • PROTECT: one에 해당하는 데이터가 삭제되지 않도록 보호합니다.
  • SET_NULL: null값으로 대체합니다. null=True 옵션이 있어야 가능합니다.
  • SET_DEFAULT: default값으로 대체합니다. default=True 옵션이 있어야 가능합니다.
  • SET: 대체할 값이나 함수를 지정합니다.
  • DO_NOTHING: 아무것도 하지 않습니다. DB에서 오류가 날 수 있습니다.

1-2. limit_choices_to

class Comment(models.Model):
    post = models.ForeignKey(
      Post,
      on_delete=models.CASCADE,
      limit_choices_to = {'is_published': True},
    )

one의 Field와 Field 값을 dictionary의 Key-Value 형태로 명시해줍니다.
이럴 경우, 필드와 필드값이 일치하는 데이터와만 관계지어질 수 있습니다.

2. OneToOneField

말 그대로 1대1 관계를 뜻합니다.

class User(AbstractBaseUser):
  # 생략

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

OneToOne의 경우 어느 쪽에서 선언해도 무방합니다.

3. ManyToManyField

# 방법 1
class Post(models.Model):
  tag = models.ManyToManyField('Tag',blank=True)

class Tag(models.Model):
  # 생략

# 방법 2
class Post(models.Model):
    # 생략

class Tag(models.Model):
  post = models.ManyToManyField(post,blank=True)

ManyToMany도 어느쪽에서 선언해도 무방합니다. 단, 아래에 있는 model을 선언해줄때는 String으로 표현해야합니다.
blank=True 옵션을 걸어준 이유는 tag를 하나도 달지 않는 경우도 있기 때문입니다.