Django의 ForeignKey
Django에서 ForeignKey는 데이터베이스 모델 간의 관계를 정의할 때 사용하는 필드
관계형 데이터베이스에서 흔히 사용되는 "외래 키"와 동일한 개념으로, 한 모델의 특정 필드가 다른 모델의 특정 레코드를 참조하도록 설정함
->두 테이블 간의 관계를 효율적으로 표현하고 관리할 수 있음
ForeignKey의 주요 특징
1. 일대다 관계 정의
ForeignKey는 일대다 관계를 나타냄
예를 들어, 블로그 포스트와 댓글 모델 간의 관계 -> 한 개의 블로그 포스트에는 여러 댓글이 달릴 수 있기 때문에 댓글 모델에서 ForeignKey를 사용하여 블로그 모델을 참조함
2. 다른 모델 참조
ForeignKey는 다른 모델을 참조하는 필드
선언 시 참조할 모델명을 전달해야 하며, 문자열로 모델 이름을 전달하거나 직접 모델 클래스를 사용할 수 있음
3. on_delete 옵션
ForeignKey 필드의 가장 중요한 옵션 중 하나는 on_delete
참조된 객체가 삭제될 때 어떤 동작을 할지 설정함
CASCADE: 참조된 객체가 삭제되면 관련된 객체도 삭제됨
SET_NULL: 참조된 객체가 삭제되면 관련된 필드를 NULL로 설정함
PROTECT: 참조된 객체 삭제를 방지함
SET_DEFAULT: 참조된 객체가 삭제되면 필드를 기본값으로 설정함
DO_NOTHING: 아무 작업도 하지 않음(데이터 무결성을 사용자가 직접 관리해야 함)
ForeignKey 선언 방법
from django.db import models
class Blog(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
class Comment(models.Model):
blog = models.ForeignKey(
Blog,
on_delete=models.CASCADE,
related_name="comments"
)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
blog: Blog 모델을 참조하는 ForeignKey 필드
on_delete=models.CASCADE: 블로그가 삭제되면 연결된 댓글도 삭제됨
related_name: 역참조 시 사용할 이름 설정 예를 들어, 블로그 객체에서 댓글 목록을 가져올 때 blog.comments.all() 형태로 접근 가능함
ForeignKey 옵션 정리
- on_delete 관계된 객체가 삭제될 때 동작을 설정하는 필수 옵션
- related_name 역참조 시 사용할 이름을 지정; 지정하지 않으면 기본적으로 모델명_set 형식이 사용됨
- related_query_name 쿼리셋에서 참조 필드를 필터링할 때 사용할 이름을 지정함
- db_constraint 데이터베이스에서 실제 ForeignKey 제약 조건을 생성할지 여부를 결정함 기본값은 True
ForeignKey를 사용하는 이유
1. 데이터 중복 방지
동일한 데이터를 여러 테이블에 저장하지 않고 참조를 통해 관리할 수 있음
2. 관계형 데이터 관리 용이
여러 테이블 간의 관계를 효율적으로 정의하고 데이터 무결성을 유지할 수 있음
3. Django ORM 활용
ForeignKey를 사용하면 ORM의 강력한 기능을 활용해 객체 간의 관계를 쉽게 조회하고 관리할 수 있음
ForeignKey 사용 시 주의할 점
on_delete 설정: 적절한 on_delete 옵션을 선택하지 않으면 데이터 무결성에 문제가 생길 수 있음
성능 고려: ForeignKey 필드를 사용할 경우 쿼리 최적화를 염두에 둬야 함 필요하다면 select_related나 prefetch_related를 사용해 성능을 개선해야 함
데이터 참조 순환: 잘못 설계하면 순환 참조 문제가 발생할 수 있음 -> 이를 방지하려면 모델 설계 단계에서 관계를 명확히 정의해야 함
'장고' 카테고리의 다른 글
Django Rest Framework (1) | 2024.12.19 |
---|---|
RESTful API (0) | 2024.12.18 |
Django ManyToManyField (0) | 2024.12.17 |
django annotate (1) | 2024.12.16 |
장고 시작하기 (0) | 2024.12.12 |