"0. 장고 form 작성"의 두 판 사이의 차이
(→기본 형태) |
(→기본 형태) |
||
80번째 줄: | 80번째 줄: | ||
<nowiki>|</nowiki>default_if_none:<nowiki>''</nowiki> 은 값을 쓰지 않았을 때 <nowiki>''</nowiki>를 담아주기 위한 것. 초기값을 지정할 수도 있다.(이걸 지정하지 않으면 입력하지 않은 값들에 'none'이라는 문자열이 담겨 꼴이 우스워진다) | <nowiki>|</nowiki>default_if_none:<nowiki>''</nowiki> 은 값을 쓰지 않았을 때 <nowiki>''</nowiki>를 담아주기 위한 것. 초기값을 지정할 수도 있다.(이걸 지정하지 않으면 입력하지 않은 값들에 'none'이라는 문자열이 담겨 꼴이 우스워진다) | ||
+ | |||
+ | == 폼 하위함수 == | ||
+ | {| class="wikitable" | ||
+ | !의도 | ||
+ | !설명 | ||
+ | !코드 | ||
+ | |- | ||
+ | |폼 하위함수 | ||
+ | |모델의 하위함수로 조작이 가능한 것처럼, 폼에서 반복되는 작업은 폼 하위함수로 처리하면 편하다. | ||
+ | |<syntaxhighlight lang="python"> | ||
+ | from django import forms | ||
+ | |||
+ | class 폼이름(forms.Form): | ||
+ | 속성 = forms.필드명() | ||
+ | 속성2 = forms.필드명() | ||
+ | |||
+ | def 함수(self): | ||
+ | '''폼에서 받은 변수는 self.cleaned_data에서 얻어올 수 있다.''' | ||
+ | 명령(self.cleaned_data['속성'], self.cleaned_data['속성2']) | ||
+ | </syntaxhighlight> | ||
+ | |} | ||
== 메타클래스 == | == 메타클래스 == | ||
2023년 1월 10일 (화) 18:05 기준 최신판
1 개요[편집 | 원본 편집]
장고에선 장고 form이라는 개념을 제공해 데이터 입력의 편의성을 제공한다. 장고에서 제공하는, 모델과 연동하여 데이터를 입력받는 기능이다. html을 자동 렌더링해준다. 폼을 통해 DB로의 입력을 제어할 수 있다.
폼을 만들고 html(탬플릿)에 {{form}} 이라고만 입력하면 자동으로 html 언어로 변환해 보여준다.
장고는 모델에 따라 적절한 형태의 폼을, 안전하게 처리해주는 기능을 갖고 있다.
모델의 제약 외에 폼에서의 제약을 설정하는 등 상세한 변형이 가능하여 많이 이용되는 개념이다.
1.1 폼의 장점[편집 | 원본 편집]
- 재활용 할 수 있다.
- 에러메시지를 자동으로 띄워준다. 탬플릿에 {{ form.error }} 변수를 띄워주면 잘못된 입력이라든가 빈 입력이라든가에 대한 피드백을 해준다.
- 서로 다른 데이터타입은 유효성 검사(에러검사)도 달리해야 하는데, 이러한 과정을 자동으로 처리해주어 적극 권장한다.
2 정의[편집 | 원본 편집]
폼을 사용하기 위해선 폼 클래스를 정의해야 한다.
일반적으로 앱의 forms.py 안에 정의한다.
2.1 기본 형태[편집 | 원본 편집]
설명 | 코드 | |
---|---|---|
모델폼 | 모델에서 사용하는 제약 그대로 사용할 경우 사용한다. | from django import forms
from .models import 모델 # 폼을 적용할 모델을 불러온다.
class 폼이름(forms.ModelForm): # 특별한 경우가 아닌 한 일반폼이 아닌, 모델폼을 사용한다.
class Meta:
model = 모델 # 사용할 모델
fields = ['필드1', '필드2',...] # 폼으로 입력할 필드를 입력해준다.
# fields에 '__all__'을 따옴표까지 함께 넣어주면 모든 필드를 가져오라는 명령이 된다.
|
일반 폼 | 모델과 별개로 입력값에 대한 유효성검사를 하고 싶을 때
(누락, 유효하지 않은 데이터형 등) |
from django import forms
class 폼이름(forms.Form):
속성 = forms.필드명()
속성2 = forms.필드명()
속성2 = forms.필드명(required=False) 형태로 넣으면 해당 필드는 비어도 된다는 의미. |
대부분 모델과 연동하여 사용하므로 모델 폼을 중심으로 설명한다.
2.2 폼필드 제약[편집 | 원본 편집]
클래스 변수로 모델의 속성명 = forms.CharField(label='보여질이름', max_length=100)
따위로 폼 안에서 입력의 제한조건을 걸 수도 있지만, 기왕 모델을 작성하는 거, 모델에서 제한조건을 완성하고 폼에선 보여지는 대상과 방식에 집중하자.
폼 필드에 일일이 제약을 걸 수는 없으니, 모델에서 제약을 걸고 폼에서는 이를 사용하기만 한다.
어차피 모델에서 알아서 폼필드를 만든다.(모델은 유효성검사를 하고, 입력 자체를 막진 못한다. 그럴 때 사용하면 된다. 혹은 HTML 코드에서 입력의 제약을 걸 수도 있는데, 각 폼마다 제약을 거는 게 아니라 한번에 {{form}} 형식으로 불러올 거라면 이곳에서 제약을 걸어주어야 한다.)
2.3 위젯[편집 | 원본 편집]
각 폼 필드는 <input type='text'>와 같은 HTML 위젯을 갖고 있다.
자동으로 태그로 감싸주기 때문에 탬플릿에서 편집이 안된다. 이렇게 되면 디자인측면에서 제약이 생기게 되는데.. 개개 입력칸을 편집하기 위해선 form의 수정이 필요하다.
각 폼필드마다 기본적인 위젯을 갖고 있다.
폼필드 안의 옵션에 속성=forms.CharFiedl(....., widget={'class'='클래스값', ...}) 와 같이 옵션을 추가해주면 된다.(역시, HTML에서 입력할 수 있기 때문에 분업을 하는 경우 굳이 사용하진 않는다.)
그런데, 위처럼 작업하면 디자이너가 .py를 만져야 한다는 점에서 디자이너와 개발자간 역할분리가 흐려지기도 한다는 단점이 있다. 이를 탬플릿에서 직접 다루기 위해선 다시 widgets 속성을 없애고, 탬플릿을 수정해준다. 다음과 같은 형식으로 폼 내부의 속성에 접근할 수 있고, 이들을 html에서 직접 편집할 수 있다.
<label for="subject">제목</label>
<input type="text" class="form-control" name="subject" id="subject"
value="{{ form.subject.value|default_if_none:'' }}">
{{form.subject}}로 접근할 수 있지만, {{form.subject.value}}를 써준 것은, 에러가 나고 페이지를 새로 불러들일 때 기존 입력값을 보존하기 위함이다.
|default_if_none:'' 은 값을 쓰지 않았을 때 ''를 담아주기 위한 것. 초기값을 지정할 수도 있다.(이걸 지정하지 않으면 입력하지 않은 값들에 'none'이라는 문자열이 담겨 꼴이 우스워진다)
3 폼 하위함수[편집 | 원본 편집]
의도 | 설명 | 코드 |
---|---|---|
폼 하위함수 | 모델의 하위함수로 조작이 가능한 것처럼, 폼에서 반복되는 작업은 폼 하위함수로 처리하면 편하다. | from django import forms
class 폼이름(forms.Form):
속성 = forms.필드명()
속성2 = forms.필드명()
def 함수(self):
'''폼에서 받은 변수는 self.cleaned_data에서 얻어올 수 있다.'''
명령(self.cleaned_data['속성'], self.cleaned_data['속성2'])
|
4 메타클래스[편집 | 원본 편집]
4.1 폼 라벨 붙이기[편집 | 원본 편집]
모델에서 사용한 속성 이름이 웹페이지에 그대로 드러나는데, 내부에서 처리하는 변수명과 외부에 드러나는 라벨이 달라야 할 때가 있다. 이 역시 form을 수정함으로써 기능한다.
class QuestionForm(forms.ModelForm):#모델폼 상속
class Meta:
labels = { # 이 속성의 추가로 나타내는 내용을 표시할 수 있음.
'subject': '제목',
'content': '내용',
}
4.2 위젯[편집 | 원본 편집]
필드에서 위젯을 다룰 수도 있지만 메타클래스를 통해 위젯을 다룰 수도 있다.
class QuestionForm(forms.ModelForm):#모델폼 상속
class Meta:
widgets = { #이 속성의 추가로 입력항목에 부트스트랩의 클래스를 추가해 넣을 수 있다.
'subject': forms.TextInput(attrs={'class': 'form-control'}),
'content': forms.Textarea(attrs={'class': 'form-control', 'rows': 10}),
}