해결된 질문
작성
·
50
·
수정됨
1
이진석 강사님 안녕하세요,
올려주신 Django 강의를 차근 차근 따라가며 즐겁게 학습하고 있습니다. 작성해주신 코드에 대한 동작 원리를 이해하려고노력하면서 수강하고 있습니다.
그 과정에서 작성하신 코드의 동작 원리에 관련해서 궁금한 게 있어서 이렇게 질문 드려요 🙂
11-10 강의에서 SignupForm 모델 폼에서 clean_email(self) 메서드를 정의하여 입력 받은 email 값에 대한 유일성을 검사하는 코드 관련해서 궁금한 점이 있습니다.
정의한 clean_email(self) 메서드는 언제 django 내부에서 호출되는지 궁금합니다. 폼의 is_valid() 메서드를 통과한 이후에 self.cleaned_data 인스턴스 변수에 사전으로 값이 담긴 이후에 호출되는 걸로 이해했는데 맞을까요?
return 값으로 email 변수 하나만 넘겨주게 구현이 되어 있는데요. email 변수만 반환하는데, email 변수에 담긴 cleaned_data 인스턴스 변수 값이 반환 된 이후에 Django 내부적으로 어떻게 처리 되는지 궁금합니다.
UserCreationForm 클래스에 clean_username(self)가 정의되어 있던데요. def clean_{field_name}(self) 의 형태로 제가 원하는 필드에 대해서 추가로 유효성 검증 로직을 구현하고 싶을 경우, 위와 같은 형태로 메서드를 추가로 정의해서 코드를 구현하면 되는 거로 이해했는데 제가 제대로 이해한 건지 궁금합니다.
감사합니다!
답변 1
1
안녕하세요.
깊이있는 질문을 주셔서 너무나 감사드립니다. ;-)
차근차근 설명드리겠습니다.
모든 장고 Form은 BaseForm 클래스를 상속받습니다. 아래 링크의 is_valid 메서드 구현을 보시면요.
https://github.com/django/django/blob/4.2.16/django/forms/forms.py#L199
아래와 같이 errors 속성 여부를 검사하게 되구요.
errors 구현에서는 유효성 검사가 수행된 적이 없을 때 full_clean 메서드를 호출하게 됩니다.
full_clean 메서드가 호출되면, errors 인스턴스 변수를 초기화하고 에러 내역을 담을 준비를 하구요. _clean_fields 메서드를 호출하여, 필드별 유효성 검사를 수행합니다. // 각 폼 필드 별로 준비된 유효성 검사를 .clean 메서드를 호출하여 수행하구요. 이어서 hasattr(self, "clean_%s" % name) 코드로 현재 폼 인스턴스에 clean_필드명 메서드가 있는 지 확인하여 있다면 호출하여, 그 반환값을 self.cleaned_data 사전에 반영합니다.
_clean_fields 메서드 구현에 두번째 질문에 대한 답도 있습니다. 각 유효성 검사 함수를 호출한 뒤에 반환값으로 받은 value 값을 self.cleaned_data[name] = value 코드를 통해 반영하고 있습니다.
세번째 질문에 대한 답변으로서, Form에서는 Form 클래스 정의 시에 validators 인자를 통해 유효성 검사 로직을 추가할 수도 있고, Form 인스턴스 생성 시에 clean_필드명 메서드를 재정의해서 유효성 검사 로직을 추가할 수도 있습니다.
구현하실려는 유효성 검사 로직이 UserCreationForm 폼 클래스에서만 필요한 1회성 로직이라면 clean_username 메서드를 통해 구현하실 수 있겠습니다.
혹은 username 필드에 대한 유효성 검사 시에 username 값 외에 다른 필드값에 대한 참조가 필요한 경우 (예를 들어, 게임 서버에서는 다수의 서버가 있고, 서버가 다르다면 다른 서버의 username을 현재 서버에서 사용할 수 있습니다. 그러니 유일성 체크에서는 server_name과 username을 같이 체크해야할 것입니다.), clean 메서드를 재정의하여 server_name 값과 username 값을 동시에 확인하여 유효성 검사를 수행하여야 합니다.
수행하실려는 유효성 검사가 다른 필드에서도 반복되어 사용이 되는 경우라면, 매 폼 필드마다 유효성 검사를 수행하시는 코드를 리팩토링해서, 커스텀 Form 필드로 구현하시고, 그 안에서 유효성 검사를 수행토록 해보실 수 있습니다.
충분한 답변이 되었을 지 잘 모르겠습니다.
살펴보시고, 추가 질문은 댓글로 남겨주세요. :-)
자세한 설명 정말 감사합니다. 🙂
강사님, 덕분에 궁금했던 코드의 내부 동작 흐름을 이해했습니다!
강의에서 정의한 clean_email 메서드가 호출되는 시점이 언제인지 강사님의 친절한 설명과 첨부해주신 소스코드 캡쳐 이미지를 보고 이해할 수 있었습니다!
value = getattr(self, "clean_%s" % name)
이 코드가 동작해서 강의에서 정의한 clean_email 메서드의 반환 값인 email 변수 값을 value 변수에 담는군요. 그리고 self.cleaned_data[name] = value 코드를 통해 cleaned_data 사전에 값을 할당하는 것도 확인했습니다 🙂
폼 객체를 통해 입력 받은 필드 값에 대한 유효성 검사 로직을 구현하는 방법이 여러가지 케이스가 있군요. 직접 프로젝트를 구현할 때 참고하겠습니다.
주말임에도 불구하고 알찬 답변 달아주셔서 정말 정말 감사합니다. 좋은 주말 보내세요!