Django를 더 Django스럽게 만들어주는 Form
2022. 1. 18. 14:53ㆍ강의 정리/Django Form
반응형
장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!
Form
- 장고를 더욱 장고스럽게 만들어주는 주옥같은 특징
- 장고에서 가장 큰 비중을 차지하고있는 것은 model이고, model과 함께 장고 Form은 매우 중요한 기능이며, Form이나 Serialize를 사용하지 않는다면 굳이 장고를 쓸 필요가 없음.
- 주요 역할
- 입력폼 HTML 생성
- 입력폼 값에 대한 유효성 검증 및 값 변환
- 유효성 검증을 통과한 값들을 dict 형태로 제공
#myapp/forms.py class PostForm(forms.Form): title = forms.CharField() content = forms.CharField(widget=from.Textarea)
- Form과 model의 차이점
- model은 데이터베이스와의 상호작용을 담당
- Form은 HTML Form과의 상호작용을 담당
- widget 기능
- HTML을 만들어주는 기능
Django Style의 Form 처리
- 하나의 URL (하나의 View)에서 2가지 역할을 모두 수행
- 빈 폼을 보여주는 역할
- 폼을 통해 입력된 값을 검증하고 저장하는 역할
- GET 방식으로 요청(request)받았을 때 즉 주소를 요청받았을 때
- New/Edit 입력폼을 보여준다.
- POST 방식으로 요청(request)받았을 때 즉 유저가 입력한 값을 전달 받았을 때
- 데이터를 폼을 통해서 입력받아서 (request.POST, request.FILES) 유효성 검증 수행
- 검증 성공 시 : 해당 데이터를 저장하고, SUCCESS URL로 이동함 #JSON 값 전달
- 검증 실패 시 : 오류 메세지와 함께 입력폼을 다시 보여줌 #에러메세지를 JSON으로 전달
- 장고에서 Form을 처리하는 일반적인 코드
def post_new(request):
# POST 요청이라면 즉 유저가 입력한 값을 전달 받았다면
if request.method == 'POST':
form = PostForm(request.POST, request.FILES) # 첫번째 인자가 데이터, 두번째 인자가 FILES
# 유효성 검사에 성공하면 True 리턴
if form.is_valid():
# 검증에 성공한 값들을 사전타입으로 제공받음
# 검증에 성공한 값을 제공받으면, Django Form의 역할은 여기까지
# 필요에 따라, 이값을 DB에 저장하기
post = Post(**form.cleaned_data) # DB에 저장하기
post.save()
# 저장하고 임의의 주소로 이동
return redirect(post)
else: # 검증에 실패하면, form.errors와 form.각필드.errors에 오류 정보 저장
form.errors
# GET 요청이라면 즉 주소 값을 전달 받았다면
else:
# 빈 Form 객체 전달
form = PostForm()
return render(request, 'blog/post_form.html',{
'form':form,
})
Model Form
- Form인데, 어떤 model로부터 어떤 Field를 가져오겠다 정의하면 Form이 model로부터 스스로 Field 정보를 가져와서 Form Field를 구성해준다. 즉 model이 변경된다면 자동으로 Model Form또한 변경된다.
- 매우 편리함!
#myapp/forms.py
class PostForm(forms.ModelForm):
class Meta: # Meta 속성의
model = Post # 해당 모델로부터
field = '__all__' # 가져올 필드 정보
필드 별로 유효성 검사 함수 추가 적용
- 장고에서는 모델단에 유효성 검사 로직을 넣을 수 있다.
- Form의 경우
# myapp/forms.py
from django import forms
def min_length_3_validator(value):
if len(value) < 3:
raise forms.ValidationError('3글자 이상 입력해주세요.')
class PostForm(forms.Form):
# 원하는 유효성 검사 로직을 validators에 수행할 함수를 지정할 수 있다.
# 함수는 필히 인자 하나만 받을 수 있고, Model단에도 넣을 수 있다.
title = forms.CharField(validators=[min_length_3_validators])
content = forms.CharField(widget=form.Textarea)
- ModelForm의 경우
# myapp/forms.py
from django import forms
def min_length_3_validator(value):
if len(value) < 3:
raise forms.ValidationError('3글자 이상 입력해주세요.')
class Post(forms.Model):
# 원하는 유효성 검사 로직을 validators에 수행할 함수를 지정할 수 있다.
# 함수는 필히 인자 하나만 받을 수 있고, Model단에도 넣을 수 있다.
title = models.CharField(max_lenth=100, validators=[min_length_3_validators])
content = models.TextField()
원래 Form을 그냥 만들 때에는 validators를 직접 필드에 지정했어야 했다. 즉 Model에도 지정을 해주어야하고, Form에도 지정을 해줘야하는데 그러면 로직이 분산되므로 관리하기가 매우 힘들다.
이 때
Model Form을 사용하면 Model단에 validators를 구현하게 되면, 자동으로 Form에도 validators 가져와진다.
우리는 Model Form을 사용함으로서 Model단에서만 validators를 지정하면 된다!!!
실제 Form 구현해보기 #1
#instagram/models.py
from django.core.validators import MinLengthValidator
# validators 객체는 함수를 반환하여준다.
# 만약 3글자 미만의 문자열을 입력받으면 forms.ValidationError를 반환한다.
min_length_Validators = MinLengthValidator(3)
class Post(models.Model):
message = models.TextField(
validators=[min_length_Validators]
)
- validators 공식 Django 문서
#instagram/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
실제 Form 구현해보기 #2
#instagram/post_list.html
<a href="{% url 'instagram:post_new' %}" class="btn btn-primary btn-block mt-4 mb-4">새 포스팅</a>
#instagram/post_form.html
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ form }}
</table>
<input type="submit" value="저장" />
</form>
- GET 요청일 때
- 유저가 Form을 채우고 submit하면 POST 요청
-
- POST 요청이지만 유효성 검증에서 실패했다면
- Form 인스턴스를 통해 HTML 폼 출력
- 오류메세지도 있다면 같이 출력
- 다시 유저가 Form을 채우고 submit하면 POST 재요청
- POST 요청이지만 유효성 검증에서 실패했다면
- method : 전송 방식
- "GET" : 주로 데이터 조회 요청시에 사용
- "POST" : 파괴적인 액션(생성/수정/삭제)에서 사용
#instagram/urls.py
urlpatterns = [
path('new/', views.post_new, name='post_new'),
]
#instagram/models.py
from django.core.validators import MinLengthValidator
# validators 객체는 함수를 반환하여준다.
# 만약 3글자 미만의 문자열을 입력받으면 forms.ValidationError를 반환한다.
min_length_Validators = MinLengthValidator(3)
# Create your models here.
class Post(models.Model):
message = models.TextField(
validators=[min_length_Validators]
)
- 유효성 검사 로직은 되도록 model에서 처리하는게 장고의 철칙!
#instagram/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
#instagram/views.py
from .forms import PostForm
from .models import Post
def post_new(request):
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
post = form.save()
return redirect(post)
else:
form = PostForm()
return render(request, 'instagram/post_form.html',{
'form' : form,
})
- view 함수 내에서 method에 따라 Form 객체 생성
- if 조건체크를 POST에 대해 먼저 체크하는 것은 장고 스타일이다.
- # GET 요청이 Form 객체 생성 이외에 특별한 역할이 없어서인듯 하다.
도움 받은 문서
반응형
'강의 정리 > Django Form' 카테고리의 다른 글
Django Form Validation (0) | 2022.01.19 |
---|---|
Django ModelForm이란? (0) | 2022.01.19 |
Django Cross Site Request Forgery이란??? (0) | 2022.01.18 |
HttpRequest, HttpResponse, JsonResponse (0) | 2022.01.17 |
Django HTML Form (0) | 2022.01.17 |