Form.py
를 만들어 볼거다!
근데 왜?
HTML로 만들었었는데??
손으로 만드는데는 한계가 있어,,
- 맨날맨날 만들어줘야돼
- 서버로 보내는데 유효성 검사도 귀찮아
- 하나하나 바꾸는 것도 힘들어
그래서!
아예 만들어두고 하나씩 갖다쓰자 이거야!
Form
= MODEL
Form 안에는 두가지 입력공간을 만들 수 있는데,
모델을 기반으로 한 입력공간
우리는 장고에서 default 로 사용하는 model 틀을 가져다가 쓸 것이기 때문에 import 해줘야 한다.
from django import forms.ModelForm
임의의 입력공간
이녀석도 이미 만들어진 거 사용할거야!
from django import forms.Form
모델 기반 입력공간 만들기 form.py
# form.py
from django import forms
class myForm(forms.ModelForm):
class Meta:
# 어떤 모델을 기반으로 한 입력공간이니??
# 그 모델 중에서 어떤 항목을 입력받을 거니??
이런 식으로 적어주면 된다.
이때, Meta
클래스가 myForm
클래스에 속해있는 모습을 볼 수 있다.
어? 이건 되게 생소한데..?
Meta class
이제 앞에서 공부했던 내용을 상기해보자.
우리는 model을 사용하기에 앞서 내가 DB에 넣어줄 내용을 models.py
에서
클래스 로 정의해서 넣어줬다.
이때, 클래스와 객체에 대한 이해를 잠깐 하고 넘어갔던 것 같은데,
클래스 = 주조틀
객체 = 주조틀로 만들어진 녀석
이렇게 이해하고 넘어가면 좋다.
그런데, 파이썬에서는 클래스들도 객체로 판단한다.
이게 무슨 소리일까??
자, 붕어빵을 만들고 싶다.
그렇다면 붕어빵 틀이 필요하다.
이것은 파이썬에 대응시킨다면 class 붕어빵
에 대응될 것이다.
그리고 이 클래스를 바탕으로 붕어빵을 만든다면,
붕어빵1 = 붕어빵()
이런식으로 객체 를 만들 수 있다.
자, 그런데 내가 이번에는 잉어빵을 만들고 싶다.
그러면 잉어빵 틀이 필요하다.
이것은 파이썬에 대응시킨다면 class 잉어빵
에 대응될 것이다.
그리고 이 클래스를 바탕으로 잉어빵을 만든다면,
잉어빵1 = 잉어빵()
이런식으로 객체 를 만들 수 있다.
그렇다면 잉어빵틀과 붕어빵틀은 더 상위 집합으로 묶는다면 뭘까?
틀 이 될 것이다.
그렇다면 틀이라는 단어로 이 두가지를 묶을 수 있지 않을까?
파이썬 코드로 말하면 이렇게 될거다.
class 틀:
class 붕어빵틀:
~~~
class 잉어빵틀:
~~~
즉 클래스들을 정의하기 위한 클래스
그게 메타클래스 이다.
그렇다면 내가 이렇게 변수에 class 틀
을 받으면 어떻게 될까?
틀1 = 틀()
나는 틀이라는 객체를 만든 것이다!
이렇게 상위 개념으로 클래스들을 묶어놓는 것을 메타클래스라고 한다.
임의의 입력공간 만들기 form.py
# form.py
from django import forms
class myForm(forms.Form):
img = forms.ImageField
text = forms.TextField
time = forms.DateTimeField
이렇게 사용하면 된다.
자세한 내용은, 실습에서 하도록 하자.
그리고 일단은, 모델을 기반으로 한 입력공간은 만드는데 집중해보자.
모델 기반 입력공간 만들기 views.py
이제 views.py
에 이녀석을 어떻게 넣을 것인지 생각해보자.
# views.py
from .form import myForm # import 해서 사용한다.
def create(request):
여기서 요청이 들어오면 create 함수가 실행되고,
우리는 import한 form을 갖다가 쓸거야.
근데 이 create가 어떤 역할을 수행할까?
- 처음
new.html
에 들어갔을 때, 빈 입력공간을 띄우자. - 이용자가 뭘 입력하면 그 입력값들을 처리하자.
어? 그러면 요청이 들어왔을 때,
1, 2 상황을 구분해야 되는데, 이걸 어떻게 구분하지?
자, 여기서 http method를 배웠던게 떠올라야 돼 (난 글렀어)
- 처음
new.html
에 들어갔을 때, 빈 입력공간을 띄우자. ==> GET - 이용자가 뭘 입력하면 그 입력값들을 처리하자. ==> POST
요청했을 때 1번은 띄우는 것 이 목표고,
2번은 보내는 것 이 목표다.
그렇기 때문에 http method 이름도 get, post 인가보다.
어떤 방식의 전송방식을 택하느냐에 따라서 다른 처리 방식을 구사하면 된다!
이건 if문으로 간단하게 구현할 수 있다.
간단한 정리
가져오는 것 = GET method
보내는 것 = POST method
여기까지 정리해보면 이런 구조다!
# views.py
from .form import myForm # import 해서 사용한다.
def create(request):
if request가 POST 이면:
2. 이용자가 입력한 값들 처리하기
else: (request가 GET 이면)
1. 빈 입력공간 띄우기
근데 여기서 끝나면 섭하니까 (으읍)
예전에 했던 것과 비교해보자.
우리가 옛날에 한 것은 blog 객체를 만들고,
여기에 DB에 넣어줘야 하는 내용이 title
, body
, date
세 정보기 때문에
이걸 모두 입력공간에 넣어버렸다.
근데 date는 그냥 자동으로 처리하고 싶은거야.
자, 이렇게 쓰면 해결할 수 있다.
# views.py
from .form import myForm # import 해서 사용한다.
def create(request):
if request가 POST 이면:
.is_vaild (적절한 값이 잘 입력되었는지 확인) # 이녀석은 잘 입력되었으면 1 아니면 0을 반환
일단 저장하지 말고 form 객체 말고, model 객체에 접근!
model 객체 안의 date 변수에 접근
model 객체 저장
else: (request가 GET 이면)
2. 빈 입력공간 띄우기
순서를 한번 음미해보면.
- 먼저 Post인지 확인
- 맞으면 입력 공간에 값이 잘 들어와있는지 확인
- 현재 입력 form에 date가 없으니 이녀석을 함수로 넣어주기 위해 저장잠깐 하지마
- 그리고 나서 model 객체 (date) 에 접근해서 함수로 값을 넣어줘
- 그다음에 전체 모델 저장
자 그러면 문제가 되는 코드는
일단 저장하지 말고 form 객체 말고, model 객체에 접근해!
가 문제가 된다.
이걸 가능하게 하는 코드는,
form.save(commit=False)
이렇게 써주면 된다.
엉? save는 저장할 때 쓰는 건줄 알았는데?
그래서 여기 안에 들어가는 commit=False
가 넘나 중요하다.
이렇게 하면 DB에 저장은 안되고, 현재 입력한 녀석의 객체 만 반환이 된다.
그러면 그 객체를 우리가 만지작해서
최종적으로 저장하면 되는 구조다!
HTML에 띄우기
{{form}}
이렇게만 입력하면 마구자비로 뜰거야
이걸 예쁘게 출력하게 하는 장고의 기본 method가 있는데,
세가지 정도를 예로 알아보고 실습으로 넘어가자!
{{form.as_table}} <!-- 입력 공간이 table 로 출력 -->
{{form.as_p}} <!-- 입력 공간이 paragraph 로 출력-->
{{form.as_ul}} <!-- 입력 공간이 unordered list 로 출력-->
후. 이해하기 쉽지 않겠지만 일단 실습으로 넘어가서
제대로 이해해보자.