pile·
백엔드·8퍼센트8퍼센트·

[장고 ORM] 역방향 참조 외래 키 찾기

장고에서 특정 모델을 가리키는 역방향 외래 키를 빠짐없이 찾아 수정하는 방법을 다룬 글이다. 순방향 참조는 필드 값만 고치면 되지만 역방향은 그 모델을 참조하는 모든 모델을 찾아야 한다. 모델 클래스의 _meta.related_objects가 그 목록을 준다.

핵심 포인트
  • 순방향 참조 수정은 대상 모델의 외래 키 필드만 update하면 끝난다.
  • 역방향 참조 수정은 그 모델을 가리키는 모든 모델을 찾아 고쳐야 한다.
  • 참조 목록은 모델 클래스의 _meta.related_objects에서 얻는다.
  • 소스코드를 눈으로 훑어 참조를 세는 방식은 다른 장고 앱에서 참조하는 경우를 놓친다.
  • related_objects에는 ManyToOneRel 외에 OneToOneRel, ManyToManyRel도 섞여 있어 수정 방식이 서로 다르다.
상세 정리
  • 예제 모델: ProductCategory에 속한 Product를 User가 Purchase하거나 Sell하는 구조로 두고 설명한다.
  • 순방향 사례: 소식지 상품들의 분류가 BOOK으로 잘못 들어가 MAGAZINE으로 바꿔야 할 때, filter 후 update로 category 필드만 고치면 된다.
  • 역방향 사례: 담당자 실수로 같은 제품이 두 번 등록돼 product_2를 지우고 product_1로 합치기로 한 상황이다.
  • 삭제 전 선행 작업: product_2를 참조하는 모델이 있으므로 그냥 지우면 안 되고 참조하는 쪽을 먼저 product_1로 바꿔야 한다.
  • 직접 지정의 위험: Purchase와 Sell만 고치는 코드는 그 둘이 참조의 전부라는 가정에 기대는데, 장고 앱은 다른 앱에서 가져다 쓸 수 있어 같은 앱 소스에 없어도 참조가 존재할 수 있다.
  • _meta의 정체: 장고 모델 클래스의 _meta는 Options 클래스의 인스턴스로 모델의 부가 정보를 담고 있고 그중 관계 정보도 들어 있다.
  • related_objects 출력: Product._meta.related_objects를 순회하면 shopping 앱의 purchase, sell 외에 statistics 앱의 productstatistics까지 나온다. 다른 앱의 참조가 실제로 드러나는 지점이다.
  • 세부 속성 셋: related_model은 참조한 모델, remote_field.name은 참조한 필드 이름, get_accessor_name()은 역참조 필드 이름을 준다.
  • 역참조 이름 규칙: ForeignKey 정의 시 related_name에 준 이름이며, 지정하지 않으면 모델 이름 뒤에 _set이 붙는다. sells로 지정하지 않았다면 sell_set이 됐을 것이다.
  • 일괄 수정 코드: related_objects를 돌면서 타입이 ManyToOneRel인 것만 남기고, remote_field.name을 키로 하는 딕셔너리를 언패킹해 filter와 update에 넘긴다.
  • 타입 필터링 이유: OneToOneRel과 ManyToManyRel은 수정 방식이 ForeignKey와 달라 예제에서는 건너뛰었을 뿐이며, 실제로 존재한다면 각각에 맞는 방법으로 고쳐야 한다.
  • 마무리 순서: 역참조를 모두 옮긴 뒤에야 product_2를 delete한다.
  • SQL 대안: 데이터베이스 쪽에서 외래 키 목록을 조회하는 방법도 있으며 Dataedo 문서를 참고로 든다.
왜 읽나장고에서 중복 레코드 병합이나 모델 삭제를 하다 참조 무결성에 걸린 적이 있다면 _meta.related_objects로 참조를 빠짐없이 훑는 패턴을 쓸 수 있다.
8퍼센트
8퍼센트 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·twilio-engTwilio Engineering·

    Programmable Messaging에서 Verify API로 마이그레이션하기

    Twilio의 Programmable Messaging API로 자체 OTP 솔루션을 운영하던 서비스가 Verify API로 전환하는 방법을 코드 예시와 함께 설명한다. Verify는 OTP 전송·검증을 위한 전용 API로, 전화번호 구매, 토큰 생성, DB 저장·만료 관리를 내부에서 처리해 개발자가 직접 구현할 코드를 크게 줄인다.

    요약 이어보기
    #authentication#twilio#sms+2
  2. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 2부

    포스타입 백엔드 엔지니어가 벡터 기반 개인화 추천 시스템을 실제 운영하며 맞닥뜨린 성능 장애와 용량 문제를 해결한 과정을 담은 2부다. 수백만 개의 벡터 KNN 검색이 피크 시간대에 전체 Elasticsearch 검색 성능을 흔드는 문제부터 클러스터 OOM 사태까지, 쿼리 최적화와 인프라 분리 두 가지 경로로 근본 해결에 이른다.

    요약 이어보기
    #elasticsearch#vector-search#recommendation-system+2
  3. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 1부

    포스타입이 태그 기반 추천의 한계를 극복하고 벡터 임베딩 기반 개인화 추천 시스템을 구축한 과정을 담은 1부다. 유사한 콘텐츠가 다른 용어를 쓰거나 동일한 태그가 전혀 다른 톤의 콘텐츠를 가리키는 문제를 임베딩 벡터로 해결하고, OpenSearch의 HNSW ANN 검색으로 수백만 벡터를 실시간 검색하는 시스템을 구축해 구매율 15% 향상을 달성했다.

    요약 이어보기
    #opensearch#vector-search#recommendation-system+2