Django Form Validation
2022. 1. 19. 14:18ㆍ강의 정리/Django Form
반응형
장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!
Form 유효성 검사가 수행되는 시점
#instagram/views.py
if form.is_valid():
유효성 검사 호출 로직 # is_valid() 호출 당시
- form.full_clean() 호출
- 각 필드 객체별로
- 각 필드객체.clean() 호출을 통해서 각 필드의 타입에 맞게 유효성 검사
- Form 객체 내에서
- 필드 이름별로 Form객체.clean_필드명() 함수가 있다면 호출해서 유효성 검사
- Form객체.clean() 함수가 있다면 호출해서 유효성 검사 #여러 필드를 동시에 검사하고싶을 때 사용
- 각 필드 객체별로
- 에러 유무에 따른 True / False 리턴
Form객체.clean_필드명() 함수
def clean_photo(self):
pass
Form에서 수행하는 2가지 유효성 검사
1. Validator 함수를 통한 유효성 검사
- 값이 원하는 조건에 맞지 않을 때, ValidationError 예외를 발생시킨다
- #리턴값은 사용되지 않음
#instagram/models.py
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
def validate_even(value):
if value % 2 != 0:
raise ValidationError(
_('%(value)s is not an even number'),
params={'value': value},
)
from django.db import models
class MyModel(models.Model):
even_field = models.IntegerField(validators=[validate_even])
2. Form 클래스 내 clean, clean_멤버함수 를 통한 유효성 검사 및 값 변경
- 값이 원하는 조건에 맞지 않을 때, ValidationError 예외를 발생시킨다
- #리턴값을 통해 값 반환
#instagram/forms.py
def clean_message(self):
message = self.cleaned_data.get('message')
if message:
message = re.sub(r'[a-zA-Z]+', '', message) # 영어를 공백으로 바꿔준다.
return message
Form clean 멤버함수에게 기대하는 것
- "필드명 Error 기록" 혹은 "Non 필드 Error 기록"
- 값이 조건에 안 맞으면 ValidationError 예외를 통해 오류 기록
- 혹은 add_error(필드명, 오류내용) 직접 호출을 통해 오류 기록
- 원하는 포맷으로 값 변경
- 리턴값을 통해서 값 변경하기
멤버 함수별, 검사 / 변경의 책임
- clean_필드명() 멤버 함수
- 특정 필드별 검사 / 변경의 책임
- Validation 예외 발생 시, 해당 필드 Error로 분류
- clean() 멤버 함수
- 다수 필드에 대한 검사 / 변경의 책임
- ValidationError 예외 발생시, non_field_errors로 분류
- add_error() 함수를 통해 필드별 Error 기록도 가능
Validators
- 함수형
- 유효성 검사를 수행할 값 인자를 1개 받은 호출 가능한 Object
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
def validate_even(value):
if value % 2 != 0:
raise ValidationError(
_('%(value)s is not an even number'),
params={'value': value},
)
- 클래스형
- 클래스의 인스턴스가 호출가능한 Object # 해당 클래스에서 __call__ 메소드를 구현하면 호출가능하게 된다.
from django.core.validators import MinLengthValidator
# validators 객체는 함수를 반환하여준다.
# 만약 3글자 미만의 문자열을 입력받으면 forms.ValidationError를 반환한다.
min_length_Validators = MinLengthValidator(3)
ModelForm을 사용한다면 Model쪽에 Validators를 지정하는게 좋다!
class Post(models.Model): message = models.TextField( validators=[min_length_Validators] )
기본 제공되는 빌트인 Validators
첫 글자가 대문자인 Validator은 클래스형이고 _로 연결된 Validator는 함수형이다. 기본 빌트인 된 Validator를 최대한 활용하는게 좋으며, 에러를 최소화 시킬 수 있다.
- RegexValidator
- EmailValidator
- URLValidator
- validate_email
- validate_slug
- validate_unicode_slug
- validator_ipv4_address,validator_ipv6_address, validator_ipv46_address
- validator_comma_separated_integer_list
- int_list_validator
- MaxValueValidator : 최댓값을 넘지않는지 여부
- MinValueValidator : 최솟값보다 작지않는지 여부
- MaxLengthValidator : 최댓값보다 길지않는지 여부
- MinLengthValidator: 최솟값보다 짧지않는지 여부
- DecimalValidator
- FileExtensionValidator : 파일 확장자 허용 여부
- validate_image_file_extension : 이미지 확장자 여부 (Pillow 설치 필수)
https://docs.djangoproject.com/en/4.0/ref/validators/#built-in-validators
모델 필드에 디폴트로 적용된 validators
- models.EmailField (CharField)
- validators.validate_email 적용
- models.URLField
- validators.URLvalidator() 적용
- models.GenericIPAdressField
- validators.ip_adress_validators 적용
- models.SlugField
- validators.validate_slug 적용
아니... 그러면 언제 Validators를 써야하고, 언제 clean을 써야해???
가급적이면 모든 validators는 model에 정의하고, ModelForm을 통해서 model validators 정보도 같이 가져와야한다.
즉 validators는 웬만하면 model에 정의하자!!
clean이 필요할 때는
- 특정 Form에서 1회성 유효성 검사 루틴이 필요할 때
- 다수 필드값에 걸쳐서, 유효성 검사가 필요할 때
- 필드 값을 변경할 필요가 있을 때 #validators는 값만 체크하고, 변경할 수는 없다.
Validators 예시 코드 #게임 회원가입시 중복 아이디 확인
from django.core.validators import MinLengthValidator
class GameUser(models.Model):
server = models.CharField(max_length=10)
username = models.CharField(max_length=20, validators=[MinLengthValidator(3)])
class Meta:
# model에서 unique_together META 속성을 지정할 수 있는데
# 쌍으로 묶어서 데이터베이스에 유니크하게(중복이 안되게) 저장해줌
unique_together = [
('server','username'),
]
class GameUserSignupForm(forms.ModelForm):
class Meta:
model = GameUser
fields = ['server','username']
def clean_username(self):
return self.cleaned_data.get('username', '').strip()
도움 받은 문서
반응형
'강의 정리 > Django Form' 카테고리의 다른 글
Django Form 삭제 구현! (0) | 2022.01.24 |
---|---|
Django Messages Framework (0) | 2022.01.24 |
Django ModelForm이란? (0) | 2022.01.19 |
Django Cross Site Request Forgery이란??? (0) | 2022.01.18 |
Django를 더 Django스럽게 만들어주는 Form (0) | 2022.01.18 |