Django

데이터 유효성 검사

체리1001 2021. 8. 30.

데이터 유효성 검사란? 

데이터가 우리가 원하는 규격에 맞는지 확인하는 과정이다.

개발자는 데이터는 완벽하지 않다는 것을 항상 생각하고 데이터를 검증해서 유효한 데이터로 만들어야 한다.

 

 

<유효성 검증 방법>

1. Field를 정의할 때 필요한 옵션 인자로 주기 

(아래의 1번,2번)

-> django의 내장 Field 옵션 사용

Model Field와 Form Field 두가지 모두 사용 가능하다.

Model form을 사용하는 경우에는 Model Field에 유효성 검사를 추가하면

Model을 기반으로 생성되는 form도 자동으로 유효성 검사가 된다. 

 

models.py 필드의 옵션으로 추가해주고

views.py에서 로직을 작성해주면 된다. -> is_valid() 함수 사용

#views.py
def post_create(request):
    if request.method == 'POST': #사용자가 전송버튼을 눌렀을 때
        post_form = PostForm(request.POST) #폼과 데이터를 바인딩해준다
        if post_form.is_valid():
            new_post = post_form.save() #바인딩된 내용을 save해주면 데이터베이스에 저장할 수 있다.
            return redirect('post-detail', post_id=new_post.id)
    else: #GET 방식일 때
        post_form = PostForm()  
    return render(request,'posts/post_form.html',{'form':post_form} )

 

2. 따로 validator를 추가해주기

validator:

임의의 값을 받아서 내부의 기준을 충족하지 않으면 ValidationError를 발생시키는 함수

여러 필드에서 사용이 가능하다.

장고에서 기본으로 제공하는 Built-in Validator를 사용하거나, 나만의 Validator를 직접 구현할 수도 있다.

 

Built-in Validator는 공식 문서에서 확인할 수 있다.

https://docs.djangoproject.com/en/3.2/ref/validators/

 

Validators | Django documentation | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

3. Form에서 유효성 검사하기

Model에서 사용했던 옵션들과 validator들은 모두 Form Field에서도 똑같이 사용이 가능하다.

Model을 사용하지 않는 Form을 만들 때는 따로 유효성 검사를 해줘야 한다.

 

(1) Form Field에 validator를 사용

#forms.py
from .validators import validate_symbols

class PostForm(forms.ModelForm):
    memo = forms.CharField(max_length=80, validators=[validate_symbols])

 

(2) clean_필드네임

모든 폼 클래스는 기본적으로 cleaned_data를 가지고 있다.

cleaned_data 안에는 폼 필드를 정의할 때 넣어준 유효성 검증을 통과한 데이터가 들어있다.

만약 폼 필드를 사용하지 않았다면 사용자가 입력한 데이터가 그대로 넘어오게 된다. 

clean_필드는 하나의 필드에 대해서만 검증이 가능하다.

또한 유효성 검사의 결과와는 상관없이 cleaned_data에서 가져온 데이터를 리턴해줘야 한다.

#forms.py

class PostForm(forms.ModelForm):
    memo = forms.CharField(max_length=80, validators=[validate_symbols])

    class Meta:
        model = Post 
        fields = ['title', 'content']

    
    def clean_title(self):
        title = self.cleaned_data['title']
        if '*' in title:
            raise ValidationError('"*"은 사용할 수 없습니다.')
        
        return title

 

 

아래의 다섯가지를 구현하며 유효성 검증에 대해 공부해보자.

 

 

(1) 모든 항목은 빈칸 없이 반드시 채워져야 한다.

 

Field의 black 인자 사용

black는 모든 필드에 기본적으로 있는 기본 옵션 인자로 폼에 빈칸을 허용할지 설정해줄 수 있는 인자이다.

기본 값은 False로 빈칸을 허용하지 않는다.

 

*null 옵션

데이터의 빈 값을 null로 저장하는 것을 허용할지를 설정해주는 옵션

 

blank vs null

black: 폼에서 비어있는 값을 허용할지

null: 빈 값을 null로 저장하는 걸 허용할지

 

비어있다는 표시는 django에서 ""과 null 두가지가 존재한다.

django에서는 문자열의 비어있는 값은 ""로 표시하는 것을 권장하고 있다.

그렇기 때문에 문자열 기반 필드에서는 blank 옵션을 true로 하면 빈 문자열이 저장된다.

즉, null을 true로 하는 옵션은 문자열 기반 필드에서 권장되지 않는다는 것이다. 

 

 

(2) 제목은 50자까지만 작성해야 한다.

max_length 값을 설정해준다.

#models.py

...
    title = models.CharField(max_length=50)
...

 

(3) 다른 제목과 중복될 수 없다.

unique 옵션 사용

기본적으로 false로 설정되어 있는데, 이 값은 true로 설정해주면

데이터베이스에 같은 형식의 데이터는 저장할 수 없게 된다.

#models.py
...
   title = models.CharField(max_length=50, unique=True,error_messages={'unique':'이미 있는 제목입니다'})
...

(에러메시지의 내용도 설정해줄 수 있다)

 

(4) 내용은 10자 이상이어야 한다.

#models.py 
from django.core.validators import MinLengthValidator

... 
   content = models.TextField(validators=[MinLengthValidator(10,'너무 짧군요. 10자 이상 적어주세요.')])
...

built in validator를 사용하기 위해서는 import를 해준 뒤,

validators=로 사용할 validator를 설정해주면 된다.

 

(5) 내용에는 #과 @를 쓸 수 없다.

#validators.py
from django.core.exceptions import ValidationError


def validate_symbols(value):
    if ("@" in value) or ("#" in value):
        raise ValidationError('"@"와 "#"은 포함될 수 없습니다.',code='symbol-err')

나만의 validator를 만들기 위해 validators.py를 만들어주고

유효성 검사 후 틀릴 경우 오류를 발생하는 ValidationError를 import 해준다.

 

#models.py
from .validators import validate_symbols

...
    content = models.TextField(validators=[MinLengthValidator(10,'너무 짧군요. 10자 이상 적어주세요.'),validate_symbols])
...

 

 

 

 

'Django' 카테고리의 다른 글

공공데이터 api post 사용 방식  (1) 2021.12.16
Django Pagination 구현하기  (0) 2021.09.03
model form  (0) 2021.08.30
폼(Form)이란?  (0) 2021.08.29
Django 배포 준비  (0) 2021.08.24

댓글