작성
·
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
안녕하세요.
답변이 조금 늦어 죄송합니다.
성지님께서 말씀하신 내용이 맞구요. 제가 조금 더 정리를 해보겠습니다. :)
장고 내부에는 SQL Compiler를 통해 SQL을 생성합니다. save, create 외에도 조회 시에도 모델 필드 값 참조가 필요하니깐요. 해당 모델 필드를 통해 SQL을 생성할 때 get_prep_value 메서드를 호출합니다.
ex) 모델 필드에서는 bool 타입이지만 데이터베이스에는 'Y', 'N' 문자열로 저장코자 할 때에 True -> 'Y', False -> 'N' 변환이 필요하겠습니다.
반대로 장고 모델/쿼리셋을 통해 데이터베이스에서 읽어온 필드값을 from_db_value 메서드를 통해, 그 모델 필드 성격에 맞는 값으로 변환합니다.
ex) 데이터베이스에서는 'Y', 'N' 문자열로 저장하지만, 장고 모델 단에서는 bool 타입으로 처리코자 할 때에, 'Y' -> True, 'N', -> False 변환이 필요하겠습니다.
어떤 값을 해당 모델 필드에 필요한 타입/값으로 변환하는 메서드입니다. 허용된 범위의 값이 아니라면 ValudationError를 발생시켜야 합니다.
ex) DateTimeField : datetime 객체인데, 장고 프로젝트에서는 timezone 지원이 켜져있다면, timezone이 있는 datetime 객체로 변환
모델의 clean 메서드와 choices 옵션 지정 시에도 값 변환을 목적으로 호출됩니다.
그리고 모델 필드에 따라 get_prep_value 메서드에서 to_python 메서드를 호출하여 값 변환을 하기도 합니다.
--
좋은 질문 주셔서 감사드리구요. 살펴보시다가 더 궁금한 점 있으시면 댓글 부탁드립니다.
화이팅입니다. :-)
요즘 외부 강의로 정신이 없어서 답변이 늦었습니다.
아래와 같은 모델 필드가 있을 때,
IPv4AddressIntegerField는 상속받은 models.CharField의 특성을 상속받습니다.
데이터베이스에 저장할 때에만 unsigned 정수로 저장하기 위해 get_internal_type 메서드를 재정의하여 PositiveIntegerField를 지정했습니다. 이는 모델의 유효성 검사와는 무관하구요. 모델에서 데이터베이스 SQL 생성 시에만 이 필드 타입을 통해 SQL을 생성합니다.
PositiveIntegerField는 4바이트로서, unsigned 정수 범위를 커버해야 하는 데요.
sqlite와 mysql은 unsigned 타입을 지원하는 반면,
postgresql과 oracle은 unsigned타입을 지원하지 않아 절반 범위의 값 밖에 담지 못합니다.
그래서, db_type 메서드를 추가로 재정의하여 postgresql은 8바이트 정수 필드 타입에 매칭되는 bigint 타입을 지정한 것이구요. oracle도 8바이트 정수 필드 타입인 number(19)를 지정한 것입니다.
05-05 장고 모델 기본 필드 챕터에서 아래와 같이 정리하고 있으니 참고 부탁드립니다.
살펴보시고, 댓글 부탁드립니다.
높은 수준의 질문에 감사드립니다. ;-)
답변 감사드립니다.
한가지 더 궁금한 점이 있는데요.
db_type은 migrate 할 때 db레벨에서 사용할 컬럼의 타입을 지정하기 위함인 것으로 알고있는데 get_internal_type은 파이썬(장고)에서 사용되는 타입을 지정하기 위함일까요?
1.유효성 검사에도 영향을 미치는 메소드인가요? 예제에서 상속은 CharField를 받았는데 get_internal_type에는 PositiveIntegerField라고 적혀져 있어서 조금 헷갈리네요.
2.예제코드에서 db_type에서 postgres와 oracle은 return한 값을 사용해서 db컬럼을 결정하도록 한 것이고 나머지는 get_internal_type을 참조하여 사전 정의된 매핑을 활용한 db 컬럼타입을 정하는 논리인가요?