[Django] 관계를 표현하는 모델 필드 (ForeignKey, OneToOneField, ManyToManyField)

cdwde·2021년 3월 30일
0

Django

목록 보기
4/13

🌝 본 포스트는 리액트와 함께 장고 시작하기 Complete + 별도로 공부한 내용으로 이루어져있습니다

🎈 ForeignKey(to, on_delete)

  • 1 : N 관계에서 N측에 명시

  • to: 대상모델 (클래스 직접 지정하거나 문자열로도 지정 가능)

  • on_delete: 1 측 record가 삭제될 때 N측인 데이터를 어떻게 처리할 것 인지?

    • CASCADE: 이와 연결되어있는 N측 데이터 삭제
    • PROTECT: 1인 쪽인 데이터가 삭제되지 않도록 방지
    • SET_NULL: null로 대체, 필드에 null=True 옵션이 있어야만 가능
    • SET_DEFAULT: default로 대체, 필드에 detault=True 옵션이 있어야 가능
    • SET: 대체할 값이나 함수를 지정
    • DO_NOTHING: 아무것도 하지 않음, DB에 따라 오류 발생할 수 있음

🚩 올바른 User 모델 지정

장고의 User 모델이 변경될 수 있으므로 ForeignKey로 참조해야 할 때
import 및 직접 참조(auth.User)해서 쓰는 것 비추천

  • 비추천
  class Post(models.Model):
    #...
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    #...
  • 추천
    특정 앱에서 User 모델 생성했을 때
  1. settings.pyAUTH_USER_MODEL 설정
  AUTH_USER_MODEL = '<앱_이름>'	#default는 auth.User
  1. models.py에서 사용
  from django.conf import settings

  class Post(models.Model):
    #...
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
    #...

🚩 reverse_name

  • default: 모델명소문자_set
  • 1 : N에서 1측에서 참조
# Post와 Comment는 1 : N 관계

class Post(models.Model):
  title = models.CharField(max_length=100)
  content = models.TextField()
  
class Comment(models.Model):
  post = models.ForeignKey(Post, on_delete=models.CASCADE)  #post_id 생성
  message = models.TextField()
  
  
>>> post = Post.objects.last()
>>> Comment.objects.filter(post=post)
>>> post.comment_set.all()
  • 이름 충돌 날 경우
    reverse_name 디폴트 명은 앱 이름은 고려하지 않고 모델명만 고려
    => FK의 reverse_name을 변경 or 한쪽 reverse_name 포기

🚩 limit_choices_to

dictionary 형태로 1인 쪽의 필드와 필드값 걸어줌

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

🎈 OneToOneFiled(to, on_delete)

  • 1 : 1 관계
  • ForeignKey(unique=True)와 비슷하지만 reverse 차이
    • User:Profile을 FK로 지정한다면 profile.user_set.first()
      => 없을 시 None 반환
    • User:Profile을 O2O로 지정한다면 profile.user
      => 없을 시 DoesnotExist 에러
  • 장고에 기본적으로 정의되어 있는 Use 모델과 이를 커스튬하여 새로 만드는 Profile 모델을 연결해 줄 때 자주 사용

🎈 ManyToManyField(to, blank=Flase)

  • M : N 관계

  • 방법 1 (추천)

class Post(models.Model):
  #...
  tag_set = models.ManyToManyField('Tag', blank=True)
  #...
 
class Tag(models.Model):
  #...
  name =models.CharField(max_length=50, unique=True)
  #...
  • 방법 2
class Post(models.Model):
  #...
 
class Tag(models.Model):
  #...
  name =models.CharField(max_length=50, unique=True)
  post_set = models.ManyToManyField(Post, blank=True)
  #...

참고
https://ssungkang.tistory.com/entry/Django-%EA%B4%80%EA%B3%84%EB%A5%BC-%ED%91%9C%ED%98%84%ED%95%98%EB%8A%94-%EB%AA%A8%EB%8D%B8-%ED%95%84%EB%93%9C-ForeignKeyOneToOneFieldManyToManyField?category=320582

0개의 댓글