본문 바로가기
프로젝트/Django - How Dimt?

Django poj.c B6) error) blank input ValueError 해결 - 10일차

by Fola 2022. 4. 27.

Code B Django 6번 글, 프로젝트 10일차 (수)

 

 

 

# 발생한 문제와 관련한 이전 글 링크

2022.04.26 - [프로젝트/Django - How Dimt?] - Django poj.c B5 ) 주류가격정보 테이블 구현 / 현재 봉착한 문제 - 9일차

 

 

 

 

1. 

html의 form태그의 POST방식으로 레코드를 생성하는 코드에서

blank=True, null=True로 지정했던 field에

input value 가 비어 있는 상태(blank)로 summit 했을 때

원하지 않는 ValueError 가 발생했다.

(캡쳐) ValueError - Field 'aged' expected a number but got ''.

 

blank=True 가 있으니 유효성 검사는 통과했어야 하고 

null=True 기 때문에 DB에 비어있는 값이 들어갔어야 했다.

 

왜일까..?

 

 

 

 

2.

같은 상황의 스택오버플로우 질문 글에는 다음과 같은 답변이 있었다. 

 

(글 캡쳐) age = models.IntegerField(blank=True, null=Trud) / Field in not required (form validation). If the field is passed in None, it will be translated to Null

 

( 링크: https://stackoverflow.com/questions/20399717/how-to-store-empty-value-as-an-integerfield )

 

 

답변과 에러 메시지를 번갈아 보고 상황은 인지했다.

 

blank 상태인 input 이 POST 방식으로 들어왔는데

비어있는 값이 None 이 아닌 null-string으로 처리되고 있었다.

 

따라서 DB Table의 Integer field에 정수가 아닌 null-string 값을 넣으려고 했기 때문에

ValueError 가 발생했다.

 

이는 또한 같은 생황의 (Integer field가 아닌) Varchar field에서는 ValueError가 발생하지 않은 이유기도 했다.

 

 

그러나 스택오버플로우의 답변은 나를 어리둥절하게 만들었다. 

만약 빈칸 입력이 들어오면 Null로 번역해준다고 했다.

(If the field is passed in None, it will be translated to Null)

 

왜 나의 Django는 blank를 Null로 번역하지 않고 null-stirng을 반환하는 것일까?

 

 

 

3.

원인은 알았으니 당장은 해결할 수 있었다.

 

# This code is the way to avoid Value Error:
# Django tries to insert ''(null string) to Integer field in DB
# But I don't know why Django doesn't translate null string to None
form.aged = request.POST.get('input_aged') if request.POST.get('input_aged') else None

 

기존 코드 뒤에  if request.POST.get('input_aged') else None 삼항연산 조건식을 넣었다.

단순히 input 값이 존재할 때만 객체에 입력하고 존재하지 않으면 None를 입력하도록 만들었다.

 

그리고 원치 않던 에러는 더 이상 나오지 않았다.

 

 

그래도 영 찝찝한 마음을 떨칠 수가 없었다.

 

왜 None을 null로 번역하지 않는 것일까??

 

 

 

 

4.

시간이 어느 정도 흐른 후에 불현듯 답을 깨달았다.

내가 blank와 None의 개념을 혼용하고 있었기 때문이었다. 

저 둘은 완전히 다르다. 전혀 다르다.

 

blank도 하나의 값이다. balnk의 value는 ''이다.

None 은 값이 없다는 뜻이다.

 

파이썬의 조건식에서는 null-string과 None 모두를 False 처리한다.

평소에 많이 사용하던 문법이기 때문에

나도 모르게 '' == None이라고 인식하고 있던 게 아닌가...

 

결과적으로는 위에 임시방편으로 작성해놓은 코드가 해결책이기는 했다.

원리를 정확하게 이해하고 나니 만족스럽고 후련했다. 

앞으로 비슷한 문제로 고생하진 않을 것 같다. 

 

 

 

 

5.

지금은 views.py 에서 직접 request.POST 인풋 값들을 받지 않고

forms.py에 forms.ModelForm을 상속받는 클래스를 거쳐서

DB 레코드 객체를 생성하는 방법을 찾아보고 있다.

 

input값의 유효성 검사를 깔끔하게 처리하기 위하여

ModelForm의 is_valid 함수를 사용하는 것이 목표.

 

 

댓글