Django 의 관계형 필드

김병욱·2020년 4월 30일
1

Django

목록 보기
9/15

잘 정리된 블로그도 존재한다.
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

ForeignKey

ForeignKey의 는 1:n 의 관계를 의미한다. 예를 들어 게시글과 댓글을 생각할 수 있다. 하나의 글에는 그 글에 해당되는 댓글이 여럿 존재하므로 ForeignKey를 충족한다.

class Post(models.Model):
	...
class Comment(models.Model):
	comment_text = models.ForeignKey(Post, on_delete=models.CASCADE)
    
  • on_delete 설정 (1:n의 관계에서 1인쪽의 데이터가 삭제되었을 시에 n인 쪽의 데이터를 어떻게 처리할것인지 설정한다.
  • on_delete의 종류
    CASCADE : 이와 연결되어 있는 모든 n쪽의 데이터를 삭제함
    PROTECT : 1쪽의 데이터가 삭제되지 않도록 보호함
    SET_NULL : null로 값을 대체하게 되어 필드에 null=True 옵션이 있어야만 가능하다.
    SET_DEFAULT : default로 값을 대체하게 되어 필드에 default=True 옵션이 있어야만 가능하다.
    SET : 대체할 값이나 함수를 지정한다.
    DO_NOTHING : 이무것도 하지 않지만 db에서 오류가 발생할 수 있다.

참고 설명 : https://vallhalla-edition.tistory.com/60

  • 상대모델에 접근하기 (이미 장고에서 상대모델의 클래스명소문자_set 이 정의되어있다, 다만 1인쪽의 모델에서만 사용가능하다)
    comment.post
    post.comment_set
    post.comment_set.all()
    post.comment_set.count()
class Comment(models.Model):
	post = models.ForeignKey(
    	Post, on_delete=models.CASCADE, limit_choices_to = {'is_published' : True},
    )

다음과 같이 딕셔너리 형태로 1인쪽의 필드와 필드값을 걸어준다. 이럴 경우 comment 입장에서 관계될 때 다음 필드와 필드값이 일치하는 Post만 관계가 맺어질 수 있다. ManyToMany에서도 동일하다.

OneToOneField

1:1 관계를 의미한다. 이 관계를 장고에 기본적으로 정의되어 있는 User 모델과 이를 커스튬하여 새로 만드는 Profile 모델을 연결해줄 때 자주 사용한다.

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

해당 관계는 두 모델 중 어느쪽에서 선언하여도 무방하다.

  • 상대모델에 접근하기
    user.profile
    profile.user

ManyToManyField

다대다 관계를 의미한다. 예시로는 Post와 Tag를 생각할 수 있다.

* 방법 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)

해당 관계는 두 모델중에서 어느 쪽에 선언하여도 무방하다. 단, 위에 있는 model에서 아래 있는 model을 지정할 때는 다음과 같이 문자열로써 표현한다. blank=True 옵션을 걸어준 이유는 글을 쓸 경우 tag를 하나도 지정안할 수도 있기 때문이다.

* 다대다 관계
class Person(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()

class Club(models.Model):
    name = models.CharField(max_length=50)
    members = models.ManyToManyField(Person)

tom = Person.objects.create(name="Tom", description="A nice guy")
bill = Person.objects.create(name="Bill", description="Good dancer")

nightclub = Club.objects.create(name="The Saturday Night Club")
nightclub.members.add(tom, bill)

위의 예제에서 members 필드는 Person과 관계형인 ManyToManyField라서 .add() 함수로 추가할 수 있다. 장고에서 ManyToMany 필드를 정의하면 자동으로 .add() 함수로 다대다관계의 db를 추가할 수 있는 함수를 제공한다는 것을 알 수 있다.

  • ManyToMany 필드는 set_all() 이 안먹힌다. all()로 관계가 맺어있는 상대db를 가져온다.

출처 : 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

profile
개발스터디

0개의 댓글