PK와 FK란? : 링크텍스트
저번시간의 PK와 FK를 설명했는데, 좀더 Fk와 그 외의 설명이 필요할거 같아 다시 새로운 글을 팠다.
Django의 모델 필드는 데이터베이스 테이블의 열(Column)을 정의하는데 사용되며, 웹 애플리케이션의 데이터 모델을 구성한다.
참조:[링크텍스트](Model field reference | Django documentation | Django (djangoproject.com))
대표적인것만 보자면,
CharField:
CharField는 짧은 문자열을 저장하기 위한 필드입니다.
max_length 매개변수로 최대 문자열 길이를 지정해야 합니다.
예: models.CharField(max_length=100)
IntegerField:
IntegerField는 정수 값을 저장하는 데 사용됩니다.
예: models.IntegerField()
FloatField:
FloatField는 부동 소수점 수를 저장하는 데 사용됩니다.
예: models.FloatField()
DateField:
DateField는 날짜를 저장하는 데 사용됩니다.
예: models.DateField()
TimeField:
TimeField는 시간을 저장하는 데 사용됩니다.
예: models.TimeField()
DateTimeField:
DateTimeField는 날짜와 시간을 저장하는 데 사용됩니다.
예: models.DateTimeField()
BooleanField:
BooleanField는 참(True) 또는 거짓(False) 값을 저장하는 필드입니다.
예: models.BooleanField(default=False)
EmailField:
EmailField는 이메일 주소를 저장하는 데 사용됩니다. 입력 값이 유효한 이메일 형식이어야 합니다.
예: models.EmailField(max_length=100)
ImageField:
ImageField는 이미지 파일을 저장하는 데 사용됩니다. 파일 업로드 기능과 함께 사용됩니다.
예: models.ImageField(upload_to='images/')
ForeignKey:
ForeignKey는 다른 모델과의 관계를 표현하는 필드입니다. 다른 모델의 인스턴스와 관련되어 있음을 나타냅니다.
예: models.ForeignKey(related_name='posts', to='Author')
ManyToManyField:
ManyToManyField는 다대다(Many-to-Many) 관계를 표현하는 필드입니다. 여러 모델 인스턴스 간의 관계를 나타냅니다.
예: models.ManyToManyField(related_name='tags', to='Tag')
SlugField:
SlugField는 URL에 사용할 수 있는 문자열을 저장하는 필드입니다. 주로 블로그 글이나 게시물의 제목을 URL 친화적인 형태로 저장할 때 사용됩니다.
예: models.SlugField(max_length=50, unique=True)
AutoField:
AutoField는 자동으로 증가하는 숫자 필드입니다. 주로 데이터베이스의 기본 키(primary key)로 사용됩니다.
좀더 추가적으로 설명할 필드들은 바로 FK와 연결이 많이된 ManyToManyField 와 OnetoOneField이다.
1. to속성
다른 앱에서 UserModel(모델이름) 불러올때 from user.models import UserModel 해줘야한다.
from user.models import UserModel
author = models.ForeignKey(user.UserModel, verbose_name = "글쓴이", on_delete=models.CASCADE)
직접적인 모델 임포트 없이 모델의 이름을 문자열로 참조할 수 있다.
이 방법은 순환 참조 문제를 방지하는 데 유용.
author = models.ForeignKey('user.UserModel', verbose_name = "글쓴이", on_delete=models.CASCADE)
2. 필드의 parameter 구조
model. CharField/... 다양한 필드들이 있고,
그 값 속성에 이미 파라미터의 키값이 설정되어져 있다.
이게 무슨말이냐 하면, option키 눌러서 charfield들어가서 option키 눌러 __init__함수로 들어가면 이미
def __init__(
self,
verbose_name=None,
name=None,
primary_key=False,
max_length=None,
unique=False,
blank=False,
null=False,
db_index=False,
rel=None,
default=NOT_PROVIDED,
editable=True,
serialize=True,
unique_for_date=None,
unique_for_month=None,
unique_for_year=None,
choices=None,
help_text="",
db_column=None,
db_tablespace=None,
auto_created=False,
validators=(),
error_messages=None,
db_comment=None,
):
이러한 순서로 함수구조가 짜여진걸 볼 수가 있다.
순서대로 짠다면 키값없이 바로 value값을 넣어주면 된다.
title = model.CharField("이름","title",False,16)
순서가 아니라면(굳이 써줄 필요가 없다던가) 키값 명시하면된다.
title = model.CharField("이름",max_length=16)
verbose_name이란 속성이 아에 구조에서 없기때문에
verbose_name:
모델의 필드가 어떻게 레이블링 될지를 보다 명확하게 지정하고 싶을 때 사용한다.
어드민이라든지 페이지에 나타나고,
코딩시 이해가 빠르게 되어 적어주는 편이 나을때도 있다.
to = '모델이름'or 'app이름. 모델이름' 가 첫번째 속성이기때문에 UserModel이 바로들어간다.
author = models.ForeignKey(UserModel, verbose_name = "글쓴이", on_delete=models.CASCADE)
3.ManyToMany 필드
ManyToManyField를 사용하면 Django는 자동으로 "브릿지 테이블" 또는 "중간 테이블"(intermediate table)을 생성한다.
이 테이블은 두 모델 간의 다대다 관계를 저장하는 데 사용하는데,
(한마디로 두테이블이 서로서로를 필요로 하고 다대다 관계에 있으면
즉, 한 저자가 여러 책을 출판할수도 있고, 북에서는 여러 작가가있을 수 있다.)
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
이렇게 만들어진 테이블 이름은 'book__authors'로 <첫 번째 모델 이름 소문자><두 번째 모델 이름 소문자>형식으로 지정된다.
book_id와 author_id라는 두 개의 외래 키가 포함된다.
중간 테이블에 추가적인 정보를 저장하고 싶다면, through 옵션을 사용하여 직접 중간 모델의 이름을 정의하여 모델링을 해주면 된다.
from django.db import models
class Student(models.Model):
name = models.CharField(max_length=100)
class Course(models.Model):
title = models.CharField(max_length=100)
students = models.ManyToManyField(Student, through='Enrollment')
class Enrollment(models.Model):
student = models.ForeignKey(Student, on_delete=models.CASCADE)
course = models.ForeignKey(Course, on_delete=models.CASCADE)
date_enrolled = models.DateField()
grade = models.DecimalField(max_digits=5, decimal_places=2)
=> 학생이 강좌를 수강할 때마다 Enrollment 객체를 생성하여
해당 학생, 강좌, 등록 날짜 및 성적을 저장
to: 이 속성은 필드가 연결될 다른 모델을 지정
related_name: 이 속성은 역관계에서 사용될 이름을 제공
역관계란 현재 모델이 아닌 다른 모델(이 경우 Tag 모델)에서 현재 모델로의 접근할 이름을 넣어주면 현재모델의 모든 객체에 접근할 수 있게된다.
class Article(models.Model):
title = models.CharField(max_length=100)
tags = models.ManyToManyField(related_name='articles', to='Tag')
class Tag(models.Model):
name = models.CharField(max_length=30)
여기서 Article 모델은 여러 Tag와 연결될 수 있고, 하나의 Tag는 여러 Article과 연결될 수 있습니다.
related_name='articles' 속성 덕분에 Tag 객체에서 연결된 모든 Article 객체에 직접 접근할 수 있습니다.
tag = Tag.objects.get(name="Python")
related_articles = tag.articles.all() # 이 태그와 관련된 모든 기사를 가져옵니다
여기서는 views.py에 있는 함수 중 모델 값을 가지고 올때 사용된다.
relate_name을 통해 더 직관적인 모델관계를 표현한다.
4. OneToOneField(일대일 관게)
한 모델의 인스턴스가 다른 모델의 한 인스턴스와만 연결될 수 있게되는 것을 말한다.
오직 서로가 서로에게 참조되는 것.
예)하나의 사용자(User)가 하나의 프로필(Profile)만 가질 수 있다
class User(models.Model):
name = models.CharField(max_length=100)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField()
그리고 사실 OneToOne은 따로 명시하지 않는 이유는 필드의 속성중 unique가 있는데 ForeignKey 값이 unique=True인것과 같은것을 뜻하기 때문이다.
unique=True 그 값을 고유하게 유지시켜주겠다는 소리,
즉 참조된 그 값은 현재테이블과의 고유참조가 된것.
예)
class User(models.Model):
name = models.CharField(max_length=100)
class Profile(models.Model):
user = models.ForeignKey(User, unique=True, on_delete=models.CASCADE)
bio = models.TextField()
4. On_delete 속성
이 속성은 관련된 객체가 삭제될 때 어떤 동작을 해야하는지를 정의한다.
여기서 on_delete 속성에 대해서 얘기하자면 6가지의 속성이 있고,
OneToOneField과 ForeignKey에서 사용되는 속성이다.
ManyToManyField에서 한 객체를 삭제해도 다른 모델의 객체에는 영향을 주지않고(이어져 있는 다른 2개의 모델들), 오직 중간테이블에서 해당객체와 관련된 모든 레코드(연결, 열)만 제거되기 때문에 이속성 자체가 필요가 없다.
필드에서 제일 많이쓰는 models.CASCADE 와 models.SET_NULL 관해 설명하자면,
관련된 객체가 삭제될 때, ForeignKey나 OneToOneField로 연결된 객체도 삭제된다.
즉, 다른 연결된 객체도 삭제되는것.
예) 글쓴이 - 블로그
=> 글쓴이가 삭제되면 글쓴이가 쓴 모든 포스팅도 삭제된다.
관련된 객체가 삭제될 때 ForeignKey 필드의 값을 NULL로 설정합니다. 이 옵션을 사용하려면 null=True 속성이 필드에 설정되어 있어야 한다.
즉, 다른 연결된 객체는 남아있고 삭제된 해당 객체만 NULL상태로 연결된것.
예) 글쓴이 - 블로그
=> 글쓴이가 삭제되면 글쓴이가 쓴 모든 포스팅에서 글쓴이가 삭제된다.