jc.jang

6강 Form Validation 본문

Django/Django - Form,ModelForm

6강 Form Validation

jangstory 2019. 9. 25. 17:34

주제

  • Form의 주요 기능으로서, 사용자로부터 입력값을 검증하는 기능이 있다.

  • 입력값을 검증할 함수를 만들면 로직을 호출하고 사용자에게 노출하는 부분은 장고가 알아서 처리해준다.

노트

  • Form 유효성 검사가 수행되는 시점

def post_new(request):
    form_cls = PostForm
    template_name = 'myapp/post_form.html'
    success_url = '/'

    if request.method == 'POST':
        form = form_cls(request.POST, request.FILES)
        if form.is_valid(): # 유효성 검사가 수행됩니다.
            post = form.save()
            return redirect(post)
    else:
        form = form_cls()

    return render(request, template_name, {
        'form': form,
    })
  • form.is_valid()로 유효성 검사가 수행된다.

 

  • 유효성 검사 호출 로직

  • form.full_clean() 호출

    1. 각 필드 객체 별로

      • 각 필드 객체.clean() 호출을 통해 각 필드 Type에 맞춰 유효성 검사

    2. Form 객체 내에서

      • 필드 이름 별로 Form 객체.clean_필드명() 함수가 있다면 호출해서 유효성 검사

      • Form 객체.clean() 함수가 있다면 호출해서 유효성 검사

  • 에러 유무에 따른 True/False 반환

 

  • Form에서 수행하는 2가지 유효성 검사

    1. Validator 함수를 통한 유효성 검사

      • 값이 원하는 조건에 맞지 않을 때, ValidationError 예외를 발생

        • 주의: 리턴 값은 사용되지 않습니다.

    2. Form 클래스 내 clean, clean_멤버함수를 통한 유효성 감사 및 값 변경

      • 값이 원하는 조건에 맞지 않을 때, ValidationError 예외를 발생

      • 리턴값을 통해 값 변환

 

  • 함수형/클래스형 Validator

    • 함수형

      • 유효성 검사를 수행할 값 인자를 1개 받은 Callable Object

    • 클래스형

      • 클래스의 인스턴스가 Callable Object

    • 모델 필드 정의 시 지정

    • Form 필드 정의 시 지정

    • ModelForm이지만, Form Field 직접 지정

  • 게임 서버에 동일한 username이 있는지 form을 통해 확인하는 코드

  • myapp/models.py

class GameUser(models.Model):
    server = models.CharField(max_length=10)
    username = models.CharField(max_length=20, validators=[MinLengthValidator(3)])

    class Meata:
        unique_together = [
            ('server', 'username'),
        ]
  • 메타 클래스의 unique_together 필드를 사용하면 해당 서버에 동일한 유저네임이 있는지 체크하는 로직을 추가 할 필요가 없다.

  • 하지만 이 필드를 몰랐다고 해도 상관없다. form에 clean() 메소드를 오버라이딩해서 ORM을 활용하여 작성 가능하다.

  • username은 공백을 제거하고 3글자 이상이어야한다. 3글자 이상인지 '확인'만 하는 것은 validators를 사용하고, 공백을 제거한 문자열을 사용해야하므로 form에서 clean_필드명을 사용한다. (아래 forms.py 코드 참고)

 

  • myapp/forms.py

class GameUserSignupForm(forms.ModelForm):
    class Meta:
        model = GameUser
        fields = ['server', 'username']
    
    def clean_username(self):
        '''
        값 변환은 clean 함수에서만 가능합니다.
        validator에서는 지원하지 않습니다.
        '''
        return self.cleaned_data.get('username','').strip()
  • clean_필드명 메소드는 특정 필드에 대한 검사 혹은 값 변환 시 사용한다.

  • validator는 값만 체크할 뿐, 값을 변경할 수 없다. 따라서 공백을 제거하기 위해서는 clean_필드명 메소드를 사용해야한다.

 

  • 이 외에도 clean이 필요한 경우는

    1. 특정 Form에서 1회성 유효성 검사 루틴이 필요할 때

    2. 다수 필드값에 걸쳐서 유효성 검사가 필요할 때

    3. 필드 값을 변경할 필요가 있을 때

 

'Django > Django - Form,ModelForm' 카테고리의 다른 글

8강 Form Template Custom Render  (0) 2019.10.03
7장 Widget Overview  (0) 2019.09.25
5강 ModelForm  (0) 2019.09.24
4강 CSRF  (0) 2019.09.24
3강 Form  (0) 2019.09.24
Comments