brunch

매거진 Django doc

You can make anything
by writing

C.S.Lewis

by 장영석 Mar 19. 2018

Django Model - ForeignKey

Relationship fields

Relationship fields

Django는 또한 관계를 나타내는 필드들을 정의한다.


ForeignKey


class ForeignKey(to, on_delete, **options)


다대일 관계이고 두 가지 위치 인수가 필요하다. 모델이 관련된 클래스와 on_delete 옵션이다.


재귀 관계를 만들기 위해서는(자신과 다대일 관계가 있는 객체) model.ForeignKey('self', on_delete=models.CASCADE)를 사용한다.


아직 정의되지 않은 모델에서 관계 생성이 필요하다면, 모델 오브젝트 자체가 아닌 관계될 모델의 이름을 사용한다.


추상 모델에서 이 방법으로 정의된 관계는 모델이 구체적인 모델로 서브클래스화 되고 추상 모델의 app_label과 관계가 없을 경우 해결된다.


다른 애플리케이션에 정의된 모델을 참조하기 위해, 애플리케이션 레이블 전체를 모델과 함께 명시적으로 지정할 수 있다. 예를 들어, ManuFacturer 모델이 다른 애플리케이션인 production에 정의되어 있다면 다음과 같이 사용해야 한다.


게으른 관계로 불리는 이 종류의 참조는, 종속적인 두 애플리케이션 간의 순환 참조를 해결할 때 유용할 수 있다.


ForeignKey에 데이터베이스 인덱스는 자동으로 생성된다. db_indexFalse로 설정하여 비활성화시킬 수 있다. 조인보다 일관성을 위한 외래 키를 만들거나 부분 또는 다중 칼럼 인덱스 같은 데체인덱스를 만든다면 오버헤드를 피할 수 있다.


Database Representation


Django는 필드 이름에 "_id"를 추가해서 데이터베이스 칼럼 이름을 생성한다. 위 예제에서 Car 모델의 데이터베이스 테이블은 manufacturer_id 칼럼을 가지게 된다. (db_column 지정을 통해 명시적으로 변경할 수 있다), 하지만 사용자 정의 SQL를 작성하지 않는 이상 코드에서 데이터베이스 칼럼 이름을 다룰일은 없다. 항상 모델 객체의 필드 이름을 통해 다룰 것이다.


Arguments


ForeignKey는 관계가 동작하는 방식에 대해 상세하게 정의된 다른 인수들을 허용한다.


ForeignKey.on_delete


ForeignKey로 참조된 객체가 삭제될 때, Django는 on_delete 인수에 정의된 SQL 제약 조건의 동작을 에뮬레이션 한다. 예제로, null이 허용된 ForeignKey가 있고 참조된 객체가 삭제될 때 null 세팅하기를 원할 경우

on_delete에 사용 가능한 값들은 django.db.models에서 찾을 수 있다.


CASCADE

연관된 것들을 삭제한다. Django는 SQL 제약 조건인 ON DELETE CASCADE의 동작을 에뮬레이션 하고 ForeignKey를 포함한 객체를 삭제한다.


PROTECT

ProtectedError 발생을 통해 참조된 객체의 삭제 방지, django.db.IntegrityError의 서브클래스


SET_NULL

ForeignKey를 null로 세팅한다. null True 설정일 경우만 가능하다.


SET_DEFAULT

ForeignKey를 기본 값으로 설정한다. ForeignKey의 기본값이 설정되어야 사용 가능하다.


SET()

SET()에 전달된 값을 ForeignKey에 설정하거나 callable일 경우 호출된 결과를 설정한다. 대부분의 경우, models.py 가져올 때 쿼리 실행을 피하기 위해 callable을 전달할 필요가 있다.


Do_NOTHING

아무런 행동도 취하지 않는다. 데이터베이스 백엔드에서 참조 무결성을 적용하면, 데이터베이스 필드에 수동으로 ON DELETE 제약조건 제약 SQL을 추가하지 않은 이상 IntegrityError가 발생한다.


ForeignKey.limit_choices_to

ModelForm 또는 admin 사용 시 필드가 렌더링 될 때, 사용 가능한 선택지를 제한을 설정한다 (기본적으로, 쿼리 셋의 모든 객체를 선택할 수 있다). 딕셔너리, Q 객체 또는 딕셔너리 또는 Q 객체를 리턴하는 callable이 사용 가능하다.

ModelForm의 필드가 is_staff=TrueUser만 나열되도록 한다. Django admin에서 도움이 될 것이다.


예를 들어, Python datetime 모듈을 날짜 범위 선택제한하여 사용될 때는 callable 폼이 도움이 될 수 있다.


limit_choices_to가 복잡한 쿼리에 유용한 Q 객체를 리턴하면,  해당 필드가 모델의 ModelAdminraw_id_fields에 나열되지 않았을 때, 어드민에서 사용 가능한 선택들에 영향을 미친다.


Note

limit_choices_to에 callable이 사용되면, 새로운 폼이 인스턴스화 될 때마다 호출된다. 또한 management command나 어드민에 의해 모델이 유효성 검증 시 호출된다. 어드민은 다양한 케이스의 폼 입력의 유효성을 여러 번 검증하기 위해 쿼리 셋을 구성하기 때문에, callable이 여러 번 호출될 가능성이 있다.


ForeignKey.related_name

관련된 객체에서 이 객체로 돌아올 관계에 사용될 이름이다. 또한 related_query_name (대상 모델의 역필터이름에 사용할 이름)의 기본 값이다. 전체 설명과 예제는 related objects 문서를 봐라. 추상 모델에 관계를 정의할 때는 related_name을 반드시 설정해야 한다. 그러면 몇몇의 특수한 문법이 사용 가능해진다.


Django가 뒤에서 관계를 생성하는 것을 원하지 않을 경우, related_name'+' 또는 '+'로 끝나도록 설정해라. 아래 예제에서 User 모델이 해당 모델과 역방향 관계를 갖지 않도록 보장한다.


ForeignKey.related_query_name

대상 모델에서 역방향 필터 이름으로 사용하기 위한 이름. 설정된 경우 related_name 또는 default_related_name이 설정되었을 경우 해당 값이 기본값이고 설정되지 않은 경우 모델의 이름이 기본값이다.

related_name처럼 related_query_name은 일부 특수 구문을 통해 앱 레이블과 클래스 보간을 지원한다.


ForeignKey.to_field

관계가 있는 관련 객체의 필드. 기본적으로, Django는 관련 객체의 기본키를 사용한다. 다른 필드를 참조하고 싶다면, 그 필드는 반드시 unique=True 이어야 한다.


ForeignKey.db_constraint

데이터베이스에서 이 ForeignKey에 대한 제약조건을 생성할지 여부를 제어한다. 기본값은 True이며 대부분 기본값을 사용한다. False로 설정하면 데이터 무결성에 매우 나쁜 방법이다. 다음에 False 설정을 원할만한 같은 시나리오가 있다.

유효하지 않은 기존 데이터가 있다.

데이터베이스가 샤딩되어있다.

False 설정을 한다면 존재하지 않는 관련된 객체에 접근할 때 DoesNotExist 예외가 발생한다.


ForeignKey.swappable

ForeignKeyswappable 모델을 가리키고 있다면 마이그레이션 프레임워크의 반응을 제어한다. True일 경우 ForeignKeysettings.AUTH_USER_MODEL의 현재 값과 일치하는 모델을 가리키고 있다면 (또는 다른 swappable 모델 세팅)  관계는 모델을 직접 사용하지 않고 세팅의 참조를 사용하여 마이그레이션에 저장될 것이다.


모델이 항상 스왑 된 모델 (예를 들어, 사용자 정의 user 모델로 특별히 설계된 프로필 모델인 경우)을 가리켜야 한다고 확신하는 경우에만 False로 재정의해라.


False로 설정하는 것이 swappable 모델을 swapped out 해도 참조할 수 있다는 것은 아니다. False는 단지 마이그레이션이 해당 ForeignKey가 항상 사용자가 정의한 모델을 정확히 참조한다는 것을 의미한다. (따라서 사용자가 지원하지 않는 User 모델로 실행하면 실패한다. )


의심스럽다면, 기본값인 True로 내버려둬라.



매거진의 이전글 Django Model - Field types
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari