관계를 표현하는 모델 필드 #OneToOneField

2022. 1. 3. 14:14강의 정리/Django Models

반응형
ORM은 어디까지나, SQL 생성을 도와주는 라이브러리이지, ORM DB에 대한 모든 것을 알아서 처리해주지는 않는다.그러므로 보다 성능 높은 애플리케이션을 만들고자 한다면, 사용할 DB엔진과 SQL에 대해 보다 높은 이해가 필요하다.

 


 

 

RDBMS에서의 관계 예시 #설계하기 나름임

1 : N 관계 -> models.ForeignKey로 표현

  • 1명의 유저(User)가 쓰는 다수의 포스팅(Post) # 다수측(Post)에 ForeignKey
  • 1명의 유저(User)가 쓰는 다수의 댓글(Comment) # 다수측(Comment)에 ForeignKey
  • 1개의 포스팅(Post)에 다수의 댓글(Comment) # 다수측(Comment)에 ForeignKey

 

1 : 1 관계 -> models.OneToOneField로 표현

  • 1명의 유저(User)는 1개의 프로필(Profile) # 관계를 User측이나 Profile측 아무 곳에 정의 해도된다. 그러나 보통 Profile 측에서 User에 대한 관계를 정의한다.
  • Django에서는 "auth"라는 앱에서 User라는 모델을 지원해준다. 물론 커스텀 User 모드를 만들 수는 있다.

 

M : N 관계 -> models.ManyToManyField로 표현

  • 1개의 포스팅(Post)에는 다수의 태그(Tag)
  • 1개의 태그(Tag)에는 다수의 포스팅(Post)

 


 

OneToOneField

  • 1 : 1 관계에서 어느 쪽이라도 가능 #USER : PROFILE

# 그러나 USER를 다루는 auth앱은 변경할 수 없기에 PROFILE에 정의를 한다.

 

 

ForeignKey(unique=True)와 유사하지만, reverse 차이 #unique=True는 테이블 내에 유일 값을 의미함

  • User : Profile을 FK(외래키)로 지정한다면 객체를 접근할 때-> profile.user_set.first() -> user
  • User : Profile을 020(OneToOneField)로 지정한다면 객체를 접근할 때 -> profile.user -> user


 

OneToOneField(to, on_delete) #인자 옵션

to : 대상모델 (1 : 1에서 USER 있는 모델

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

# User는 auth에 자동 설정 되있기 때문에 User와 Profile을 다룰 때 위 코드는 거의 고정이다.

 

 

on_delete : Record 삭제시 (1 : 1의 관계에서 USER에 있는 레코드가 삭제될 때 PROFILE측에 속한 USER측 레코드들을 어떻게 처리할지에 대한  ) Rule

  • CASCADE : FK로 참조하는 다른 모델의 Record도 삭제 # 디폴트 값
  • PROTECT : ProtectedError를 발생시키며, 삭제 방지
  • SET_NULL : null로 대체, 필드에 null=True 옵션 필수
  • SET_DEFAULT : 디폴트 값으로 대체. 필드에 디폴트 값 지정 필수
  • SET : 대체할 값이나 함수 지정. 함수의 경우 호출하여 리턴값을 사용
  • DO_NOTHING : 어떠한 액션 X. DB에 따라 오류가 발생할 수도 있음

 

 

 

#accounts/models.py

from django.conf import settings
from django.db import models

# Create your models here.

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    address = models.CharField(max_length=100)
    zipcode = models.CharField(max_length=6) # validators=[])를 통해서 숫자만 쓰일 수 있게 유효성 검사를 할 수 있다.

 

#accounts/admin.py

from django.contrib import admin
from .models import Profile
# Register your models here.

@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
    pass

 

 

 

 

 

# User와 Profile은 OneToOneField이기에 한 유저는 한개의 Profile만 생성할 수 있다!!!!

 

 

 


 

OneToOne에서의 즉 related_name

# reverse 접근 시의 속성명 : 디폴트 -> "모델명소문자"

related_name="author")

 

# 아래 코드는 모델의 데이터에 접근하기 위한 기본 코드이다.

from django.contrib.auth import get_user_model
# 유저 모델을 변수에 넘겨줌 
User = get_user_model()
# 유저의 모든 객체를 변수에 넘겨줌
user = User.objects.first()

 

 

# 프로필이 언제 만들어지냐면 유저가 만들어지면 Django의 시그널(일종의 이벤트 핸들러같은 개념인데 User 모델이 Save, 생성되면 호출되는 함수를 지정할 수 있다.) 에서 프로필이 자동 생성되도록 로직으로 유저와 프로필이 항상 존재함을 나타내는 방법으로 많이 구현한다.

https://dgkim5360.tistory.com/entry/django-signal-example

 

django signal의 이해를 위한 간단한 예제

django 프레임워크는 어떤 특정한 일을 수행할 때마다 알려줄 것을 설정하고, 그 때에 지정한 동작을 수행할 수 있게 하는 신호(signal)를 발생하는 기능을 가지고 있다. 자바스크립트의 이벤트를

dgkim5360.tistory.com

 

반응형