Inflearn brand logo image

인프런 커뮤니티 질문&답변

성지님의 프로필 이미지
성지

작성한 질문수

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트 (장고 4.2 기준)

07-01 커스텀 모델 필드 예제 (IPv4AddressIntegerField 설명)

07-01 IPv4AddressIntegerField 질문

작성

·

31

0

안녕하세요 강사님.

 

강의자료 소스코드 메소드 각각에 대한 세부적인 설명은 자세히 없는 것 같아 질문드립니다. 혹시 틀리거나 부족한 부분이 있다면 설명 부탁드립니다!
https://gist.githubusercontent.com/allieus/6134497ba5e0f0aa541a18b700fe9a0e/raw/212aff65dd66095455b2bc87564470f4ba8a5219/IPv4AddressIntegerField.py

1. to_python, get_prep_value, from_db_value 세가지 메소드의 공통점은 value값을 적절한 형식으로 변환하는 것 같은데요. 차이점은 아래와 같이 이해하면 될까요?

-get_prep_value: save(), create() 메소드 사용시 호출되는 내부 메소드

-from_db_value: 데이터베이스에서 오브젝트/쿼리셋을 가져올 때 호출되는 내부 메소드

-to_python: ModelForm을 통해 입력받거나 모델.<필드명> = "192.168.56.1" 처럼 직접 필드값을 할당할 때 호출되는 내부 메소드.

 

 

답변 1

0

이진석님의 프로필 이미지
이진석
지식공유자

안녕하세요.

답변이 조금 늦어 죄송합니다.

성지님께서 말씀하신 내용이 맞구요. 제가 조금 더 정리를 해보겠습니다. :)

get_prep_value 메서드

  • 장고 내부에는 SQL Compiler를 통해 SQL을 생성합니다. save, create 외에도 조회 시에도 모델 필드 값 참조가 필요하니깐요. 해당 모델 필드를 통해 SQL을 생성할 때 get_prep_value 메서드를 호출합니다.

    • ex) 모델 필드에서는 bool 타입이지만 데이터베이스에는 'Y', 'N' 문자열로 저장코자 할 때에 True -> 'Y', False -> 'N' 변환이 필요하겠습니다.

from_db_value 메서드

  • 반대로 장고 모델/쿼리셋을 통해 데이터베이스에서 읽어온 필드값을 from_db_value 메서드를 통해, 그 모델 필드 성격에 맞는 값으로 변환합니다.

    • ex) 데이터베이스에서는 'Y', 'N' 문자열로 저장하지만, 장고 모델 단에서는 bool 타입으로 처리코자 할 때에, 'Y' -> True, 'N', -> False 변환이 필요하겠습니다.

to_python

  • 어떤 값을 해당 모델 필드에 필요한 타입/값으로 변환하는 메서드입니다. 허용된 범위의 값이 아니라면 ValudationError를 발생시켜야 합니다.

    • ex) DateTimeField : datetime 객체인데, 장고 프로젝트에서는 timezone 지원이 켜져있다면, timezone이 있는 datetime 객체로 변환

  • 모델의 clean 메서드와 choices 옵션 지정 시에도 값 변환을 목적으로 호출됩니다.

  • 그리고 모델 필드에 따라 get_prep_value 메서드에서 to_python 메서드를 호출하여 값 변환을 하기도 합니다.

--

좋은 질문 주셔서 감사드리구요. 살펴보시다가 더 궁금한 점 있으시면 댓글 부탁드립니다.

화이팅입니다. :-)

성지님의 프로필 이미지
성지
질문자

답변 감사드립니다.

한가지 더 궁금한 점이 있는데요.

 

db_type은 migrate 할 때 db레벨에서 사용할 컬럼의 타입을 지정하기 위함인 것으로 알고있는데 get_internal_type은 파이썬(장고)에서 사용되는 타입을 지정하기 위함일까요?

1.유효성 검사에도 영향을 미치는 메소드인가요? 예제에서 상속은 CharField를 받았는데 get_internal_type에는 PositiveIntegerField라고 적혀져 있어서 조금 헷갈리네요.

2.예제코드에서 db_type에서 postgres와 oracle은 return한 값을 사용해서 db컬럼을 결정하도록 한 것이고 나머지는 get_internal_type을 참조하여 사전 정의된 매핑을 활용한 db 컬럼타입을 정하는 논리인가요?

이진석님의 프로필 이미지
이진석
지식공유자

요즘 외부 강의로 정신이 없어서 답변이 늦었습니다.


아래와 같은 모델 필드가 있을 때,

  1. IPv4AddressIntegerField는 상속받은 models.CharField의 특성을 상속받습니다.

  2. 데이터베이스에 저장할 때에만 unsigned 정수로 저장하기 위해 get_internal_type 메서드를 재정의하여 PositiveIntegerField를 지정했습니다. 이는 모델의 유효성 검사와는 무관하구요. 모델에서 데이터베이스 SQL 생성 시에만 이 필드 타입을 통해 SQL을 생성합니다.

     

image.png
  1. PositiveIntegerField는 4바이트로서, unsigned 정수 범위를 커버해야 하는 데요.

    1. sqlite와 mysql은 unsigned 타입을 지원하는 반면,

      postgresql과 oracle은 unsigned타입을 지원하지 않아 절반 범위의 값 밖에 담지 못합니다.

    2. 그래서, db_type 메서드를 추가로 재정의하여 postgresql은 8바이트 정수 필드 타입에 매칭되는 bigint 타입을 지정한 것이구요. oracle도 8바이트 정수 필드 타입인 number(19)를 지정한 것입니다.

05-05 장고 모델 기본 필드 챕터에서 아래와 같이 정리하고 있으니 참고 부탁드립니다.

image.png

살펴보시고, 댓글 부탁드립니다.

높은 수준의 질문에 감사드립니다. ;-)

성지님의 프로필 이미지
성지

작성한 질문수

질문하기