데이터 테이블 간의 관계를 나타내는 FK, OneToOne, ManyToMany 필드에 대해서 설명하시오
- FK Foreignkey
외래키. 다른 테이블을 식별할 수 있는 키를 말하며 테이블과 테이블을 연결하기위해 사용하는 키.
외래키를 가지고 있는 테이블을 부모테이블, 외래키가 포함된 테이블을 자식 테이블이라 한다
DB의 복잡한 구성과 조회에 오랜 시간이 걸리는 것을 피하기 위해 하나의 테이블에 모든 값을 담지 않고 외래키를 사용하여
두 개 이상의 테이블로 만들고 각각을 관리하는 방식을 사용할 때 효율적이고 간단한 구조를 만들 수 있다.
ex) 게시글과 댓글
class Feed(models.Model):
title = models.CharField(max_length=50, help_text="feed title")
content = models.TextField(help_text="feed content")
class Comment(models.Model):
feed = models.ForeignKey("Feed", on_delete=models.CASCADE, related_name="feed")
text = models.TextField(help_text="Comment text")
- O2O OnetoOne
1대 1 관계, Foreignkey에 unique= True 속성을 넣은 것과 동일하다.
1개의 주 테이블이 1개의 부테이블을 갖는 것. 유저와 프로필 관계 등에 사용한다
주테이블 혹은 부테이블 중 어느쪽을 연결해 id값을 받을지 선택이 가능하며,
커스텀에 따라 주 테이블의 Id값을 그대로 받아 사용할 수도 있다
보통은 많이 사용하는 주 테이블에 부 테이블의 id값을 넣어두고, 해당 id 값을 참조해 읽어오는 방식을 많이 사용한다
=> 주 테이블만 조회해도 대상 테이블에 데이터가 있는기 확인이 가능하기 때문! **값이 없을경우 null을 허용해야한다
부테이블에서 OneToOne 필드로 연결
class User(models.Model):
name = models.CharField(max_length=50, help_text="user name")
email = models.EmailField(help_text="user email")
password = models.CharField(max_length=128)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
nickname = models.CharField(max_length=24)
introduction = models.TextField(null=True, blank=True, default=None)
주테이블에서 외래키 unique=True로 받기
class User(models.Model):
name = models.CharField(max_length=50, help_text="user name")
email = models.EmailField(help_text="user email")
password = models.CharField(max_length=128)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, unique=True, related_name="user")
class Profile(models.Model):
nickname = models.CharField(max_length=24)
introduction = models.TextField(null=True, blank=True, default=None)
- M2M ManytoMany
다대다 관계, 한 테이블의 여러 레코드가 다른 테이블의 여러 레코드와 연결되어있는 관계를 말한다.
어느 한쪽 테이블에 manytomany필드로 참조하고자 하는 테이블을 필드로 생성하면 M2M테이블을 생성할 수 있고,
특정 기능에 다수의 옵션이 필요할때 사용한다.
장고에서 ManyToManyField를 정의하면, 자동으로 두 테이블 사이의 관계를 관리해주는 중간 테이블을 생성하며,
이 중간테이블은 각각의 테이블의 id값을 필드로 가지는데 각 테이블에 데이터가 존재하지 않으면 중간 테이블도 생성되지 않는다.
class User(models.Model):
name = models.CharField(max_length=10)
community = models.ManyToManyField('Community')
class Community(models.Model):
title = models.CharField(max_length=100)
**특징**
데이터를 가져올때 _set을 붙여 해당 내용을 불러오거나, related_name을 정의하여 해당 내용을 불러올 수 있고,
데이터의 추가와 쿼리가 양쪽에서 가능하다
community = models.ManyToManyField('Community', related_name = 'user')
>>> community.user_set.all()
>>> community.user.all()
**related_name이 '해당 테이블에서 참조하고 있는 테이블 데이터를 가져올 때 사용하는 이름'이므로
참조하고자하는 테이블의 이름을 정의해주어야 한다!
개발자가 직접 through 모델을 정의하여 필드를 추가한 중간테이블을 생성할 수 있다.
아래는 이전 프로젝트의 User모델과 Follow Bookmark 예시
class User(AbstractBaseUser):
email = models.EmailField(max_length=100, unique=True)
password = models.CharField(max_length=100)
name = models.CharField(max_length=20)
followings = models.ManyToManyField("self", symmetrical=False, through='Follow')
bookmark = models.ManyToManyField("alchol.Alchol", default=[], through='BookMark')
class Follow(models.Model):
following = models.ForeignKey('User', on_delete=models.CASCADE, null=True, related_name='follower')
follower = models.ForeignKey('User', on_delete=models.CASCADE, null=True, related_name='following')
class BookMark(models.Model):
marked_user = models.ForeignKey('User', on_delete=models.CASCADE, null=True, related_name='marked_user')
alchol = models.ForeignKey('alchol.Alchol', on_delete=models.CASCADE, null=True)
Django에서 ManyToMany필드를 만드는 방법에 대해서 설명하시오
장고에서 manytomany필드를 만드는 방법에는 2가지가 있다.
1. 중간테이블을 직접 생성하고 ForeignKey로 서로를 연결하는 방법 ( User -< Bookmark >- Community )
2. ManyToManyField를 사용해서 설정하는 방법. ( User(Bookmark) >-< Community )
일반적인 테이블을 만드는 것처럼 모델을 생성하고 필드를 설정할때,
ForeignKey 혹은 M2M를 사용하여 필드를 생성하면 다대다 관계를 만들 수 있다.
ManyToMany필드로 연결한 테이블은 장고 orm에서 인식하여 자동으로 중간 테이블을 생성해주며,
중간테이블은 고유의 index값과 연결된 모델 각각의 id값을 가진다.
ForeignKey로 서로 연결하는 코드 예시
테이블의 확장성을 고려해 명시하는 방법!! through 모델
class User(models.Model):
name = models.CharField(max_length=10)
bookmark = models.ManyToManyField("Communnity", default=[], through='BookMark')
class Community(models.Model):
title = models.CharField(max_length=100)
class BookMark(models.Model):
user = models.ForeignKey('User', on_delete=models.CASCADE, related_name='bookmarked_community')
community = models.ForeignKey('Community', on_delete=models.CASCADE, related_name='bookmarked_user')
ManyToManyField로 생성하는 코드 예시
class User(models.Model):
name = models.CharField(max_length=10)
bookmark = models.ManyToManyField('Community')
class Community(models.Model):
title = models.CharField(max_length=100)
'취대넓얕' 카테고리의 다른 글
[기술면접] 5일차 문답 | 테스트코드 Fixture CSRF (0) | 2023.07.25 |
---|---|
[기술면접] 4일차 문답 | FBV CBV 테스트코드 TDD (2) | 2023.07.24 |
[기술면접] Django 문답 | DRF, sqlite (0) | 2023.07.24 |
[기술면접] 2일차 문답 | Django Template, CRUD (0) | 2023.07.21 |
[기술면접] 1일차 문답 | Django 장점 특징 (0) | 2023.07.20 |