django form validator
django form에서 validator 커스텀
장고에서 모델 객체에 대한 유효성 검사는 보통 view에서 이루어진다.
유효성 검사를 위한 기준은 기본 모델 필드 속성 마다 정의되어 있으나 form과 model에서 별도로 개발자의 입맛에 맞게 추가적인 설정이 가능하다.
이번 글에선 form에서 validator를 재정의 하는 법을 알아보자.
장고 form class
우선 장고 깃헙에서 form 클래스가 정의 된 부분을 확인해보자.
form class github : https://github.com/JunghoGIT/django/blob/main/django/forms/forms.py
def full_clean(self):
"""
Clean all of self.data and populate self._errors and self.cleaned_data.
"""
self._errors = ErrorDict()
if not self.is_bound: # Stop further processing.
return
self.cleaned_data = {}
# If the form is permitted to be empty, and none of the form data has
# changed from the initial data, short circuit any validation.
if self.empty_permitted and not self.has_changed():
return
self._clean_fields()
self._clean_form()
self._post_clean()
def _clean_fields(self):
for name, bf in self._bound_items():
field = bf.field
value = bf.initial if field.disabled else bf.data
try:
if isinstance(field, FileField):
value = field.clean(value, bf.initial)
else:
value = field.clean(value)
self.cleaned_data[name] = value
if hasattr(self, 'clean_%s' % name):
value = getattr(self, 'clean_%s' % name)()
self.cleaned_data[name] = value
except ValidationError as e:
self.add_error(name, e)
def _clean_form(self):
try:
cleaned_data = self.clean()
except ValidationError as e:
self.add_error(None, e)
else:
if cleaned_data is not None:
self.cleaned_data = cleaned_data
def _post_clean(self):
"""
An internal hook for performing additional cleaning after form cleaning
is complete. Used for model validation in model forms.
"""
pass
def clean(self):
"""
Hook for doing any extra form-wide cleaning after Field.clean() has been
called on every field. Any ValidationError raised by this method will
not be associated with a particular field; it will have a special-case
association with the field named '__all__'.
"""
return self.cleaned_data
유효성 검사와 관련된 부분만 가져와봤다.
코드 전체를 딱 보고 이해할 순 없지만 대략적으로 파악해보면 clean 함수를 통해 유효성 검사를 하겠다 이말이다.
clean 을 사용하여 validator 커스텀
필드별로 선언
from django import forms
from .models import Note
class NoteForm(forms.ModelForm):
class Meta:
model= Note
fields =[
'title',
'content',
]
def clean_title(self):
clean_title = self.cleaned_data['title']
if '바보' in clean_title:
raise forms.ValidationError("바보는 나쁜 말")
return clean_title
def clean_content(self):
cleaned_content = self.cleaned_data['content']
if '멍청이' in cleaned_content:
raise forms.ValidationError("멍청이는 나쁜 말")
return cleaned_content
clean_[필드명]
으로 인스턴스 함수를 선언self.cleaned_data
를 통해 인스턴의 값을 가져오기- 원하는 조건 설정
- ValidationError 발생시키거나 해당하는 필드의 값을 return
주의할 점은 함수가 오버라이딩 되는 방식이기 때문에 함수명은 위의 구조를 꼭 지켜주어야 한다.
필드 전체적으로 선언
from django import forms
from .models import Note
class NoteForm(forms.ModelForm):
class Meta:
model= Note
fields =[
'title',
'content',
]
def clean(self):
cleaned_content = self.cleaned_data['content']
clean_title = self.cleaned_data['title']
if '바보' in clean_title:
raise forms.ValidationError("바보는 나쁜 말")
elif '멍청이' in cleaned_content:
raise forms.ValidationError("멍청이는 나쁜 말")
return self.cleaned_data
- clean 을 사용하게 되면 필드별 설정은 불가능하다.
- 혹시라도 clean_필드 와 같이 사용하지 않게 주의하자.
- 만약 전체적으로 적용하고 싶은 validator와 각 필드별 validator가 존재한다면 model에서 정의하는 것이 좋은 방법이라 생각됨.
댓글남기기