form은 무엇인가? 정확한 정의를 할 수 없더라도 어떤 역할을 하는지는 저번 시간에 알아봤다.
생성, 수정 과정에서 우리는 사용자로부터 입력을 받기위해 html 파일에서 form을 사용했다.
이와 더불어 두 작업은 DB에 영향을 주기 때문에 GET 요청이 아닌, POST 요청이라 하였고, POST 요청에는 csrf token이 필수적이라고 하였고 이는 유효성 검사의 일부분이다.
- 수집한 데이터가 정확하고 유효한지 확인하는 과정
- 유효성 검사를 구현하기 위해서는 많은 것들을 고려해야 함
- 이런 기능은 직접 개발하는 것이 아닌 Django가 제공하는 Form을 사용
사용자 입력 데이터를 수집하고, 처리 및 유효성 검사를 수행하기 위한 도구
유효성 검사를 단순화하고 자동화 할 수 있는 기능 제공



먼저 App 안에 forms.py 파일을 만들고 form class인 ArticleForm을 들고온다.
View 함수 안에서 바로 form을 들고오는 방법은 import만 받으면 인스턴스 생성할 수 있다.
form을 html에 render의 세번째 인자로 넘기고 html에서는 변수로 바로 사용하면 된다.
만약 각 label, input 요소를 html 태그로 묶어서 보여지게 하고 싶다면 Form rendering options를 사용할 수 있는데 이는 공식문서를 참고하면 된다. 예시는 아래 코드를 참고하면 된다.

코드를 적용해보면 content 칸이 너무 작게 나오는 걸 확인할 수 있는데, 이를 해결하기 위해서는 Widget을 사용하면 된다. 단순히 input 요소의 속성 및 출력되는 부분을 변경하는 기능으로 아래 코드를 참고해보자. 추가 기능이 필요하다면 마찬가지로 공식문서를 찾아보자!

Form 과 ModelForm의 차이를 먼저 이해한다면 더욱 이해가 쉬울 것이다.
Form : 사용자의 입력 데이터를 DB에 저장하지 않을 때 사용 (ex - 로그인)
ModelForm : 사용자의 입력 데이터를 DB에 저장해야할 때 사용 (ex - 게시글, 회원가입)
어라? 그렇다면 위에서 작성한 form은 title, content를 기록하는 article이므로 DB에 저장되어야하니 ModelForm으로 바꿔야겠네 -> 정답
ModelForm이란
Model과 연결된 Form을 자동으로 생성해주는 기능을 제공

신기한 것은 내가 전에 정의해둔 Article class를 가져와서 적용해줬기 때문에 fields를 따로 정의하지 않았다. 그런데 받아올 때 class Meta를 적게 되는데 우리가 Django의 깊은 내장 코드에 깊이 관심을 가지지 않기로 했기 때문에 넘어가도 되는 부분이지만 쉽게 말해, Meta class는 ModelForm의 정보를 작성하는 곳이라고 생각하면 된다. 혹시 제외하거나 특정 fields만 가져오고 싶다면 fields 속성을 조작하면 된다.


이제 코드의 길이가 늘어나더라도 보는 눈이 높아졌을 것이니 겁은 먹지 말고 두 가지에 집중해서 보자. 첫째, ArticleForm() 의 인자에 request.POST 이다. 파이썬 OOP 시간에 클래스 뒤의 인자는 인스턴스의 속성값을 넣는 것으로 알고 있다. 그렇다면 이해가 쉽지 않은가? 우리는 ModelForm 을 사용하여 사용자의 입력값을 받고 이는 DB에 저장될 것이기 때문에 request의 POST 값으로 입력받을 것이며 그 안에 속성값들이 다 들어있을테니, request.POST의 형태로 인자에 들어가게 된다. 둘째, if form.is_valid(): 라는 부분인데 "유효성 검사" 라는 5글자가 떠오른다면 정답이다. 우리가 form을 사용하는 가장 궁극적인 목적은 유효성 검사였음을 잊으면 안된다. 그렇다면 Django의 깊은 어딘가에서 유효하지 못한 data가 들어왔을 때 error message를 반환해줄 것이다. 그래서 (올바른 data라면) -> (저장해) 의 로직인 셈이다.

정말 이제는 모든 코드가 읽힌다. 딱 하나 instance=article가 뭐지? 인스턴스의 instance 속성이 무슨 속성인가? 우리가 사용자가 되어보자. 내가 현재 수정을 하는지 생성을 하는지 구분할 수 있는 가장 명확한 차이는 무엇인가? 수정이라함은 기존 어떤 데이터가 있었는지 떠있어야 할 것이고 생성은 빈 form이 떠있어야 할 것이다. 그 역할을 하는 것이 instance 속성이 된다.

edit한 내용을 DB에 저장하기 위한 update 함수는 크게 이해하기 어렵지 않을 것이니 천천히 읽어보도록 하자!
아주 중요한 CRUD의 과정을 ModelForm을 활용하여 진행해보았는데, 사실 의문이 드는 것이 있다. new, create 두 함수는 결국 게시글 생성의 역할을 하고, edit, update는 게시글을 수정하는 역할을 한다. 두 함수를 하나로 합칠 수 없을까? url -> view -> html 의 순서로 진행되니 합친다면 훨씬 효율적인 코드가 될 것이다. 파이썬의 기술로 한 번 합쳐보자. new와 create의 차이는 new는 GET 요청, create는 POST 요청에 대한 처리를 담당하고 있기 때문에 이로 구분하면 될 것이다.

파이썬의 논리로 합친 것까지는 이해가 될테니 오른쪽의 create함수를 다시 한 줄 한 줄 뜯어보자. 우리가 게시글 생성이라는 버튼을 누른다면(GET요청) 게시글을 생성할 수 있는 form을 제공해줘야 할 것이다. 그래서 else 구문으로 먼저 들어오게 된다. form을 들고와서 new.html에 context로 담아 보낸다. 그럼 현재 html 파일이 보이지는 않지만 action="articles:create", method="POST"와 csrf 토큰과 함께 폼을 제공할 것이다. 그럼 사용자는 data를 form에 담아 다시 보낼 것이고 이는 action에 의해 다시 create 함수로 되돌아온다. 그럼 이제 그 요청은 POST 요청이므로 if문에 접근하게 된다. 유효성 검사를 통과한다면 DB에 데이터를 저장하고 detail 페이지로 redirect 해주며 마무리된다.
방금 아주 중요한 내용을 배웠고 앞으로 다룰 모든 코드가 두 함수가 합쳐진 위의 형태와 유사하게 진행될 것이다. 반드시 복습을 철저히 해둬야하며, 가장 기억해야할 내용은 user 입장에서 코드를 작성하는 것이다. GET요청 먼저 -> POST 요청에 대한 로직 처리 결국 if 문보다 else문을 먼저 작성해야함을 잊지말자!
마찬가지로 edit, update함수도 합쳐보자.

이 코드의 해석은 여러분께 맡깁니다!