웹프로그래밍/Django

[Django] Form 과 validations

ssung.k 2019. 8. 8. 22:21

django 로 프로젝트를 진행하면서 예상 외의 난관에 봉착했습니다. 회원가입을 구현하는 과정에서 회원가입의 input 이 너무나도 많았습니다. 이를 하나씩 input 태그를 만들어주고 views 에서 값을 하나씩 받아오니 반복적인 코드가 많아졌습니다. django 는 이러한 문제를 form 을 통해서 해결하고 있었고 막상 사용해보니 form 의 중요성을 새삼 느낄 수 있었습니다. 그래서 form 에 대한 기초부터 전반적인 부분을 정리하고자 합니다.

django 에서의 form style

아직 많은 프레임워크를 써보지 않아 공감은 잘 안되지만 각 프레임 워크마다 코딩 스타일이 있다고 합니다. django 같은 경우에는 하나의 url 에 대해 두 가지 역할을 모두 수행하도록 하는 것이 그 특징입니다.

request 방식에 따라 다음 두 가지 역할을 하나의 url 에서 수행합니다.

  1. 빈 폼 보여주기
  2. 폼을 통해 입력된 값을 검증하고 저장

form 을 이용해서 새 글 작성

form 부분을 제외한 전체적인 코드에 대한 설명은 생략하도록 하겠습니다.

# models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=10)
    content = models.TextField()

단순히 제목과 내용만을 저장하는 Post 모델을 생성합니다.

# core/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('',views.home, name="home"),
    path('post_create/', views.post_create, name="post_create"),
]

url 은 메인화면 home 과 글을 쓰는 post_create 가 있습니다.

<h1>새 글 작성</h1>
<form action="" method="POST">
  {% csrf_token %}
  <table>
    {{form.as_table}}
  </table> 
  <input type="submit" value="제출">
</form>

form 만을 넘겨주게 되면 forms.py 에서 지정해준 필드에 맞게 자동으로 label 과 input을 만들어줍니다.

<tr>
  <th><label for="id_title">Title:</label></th>
  <td><input type="text" name="title" required id="id_title"></td>
</tr>
<tr>
  <th><label for="id_content">Content:</label></th><td>
  <textarea name="content" cols="40" rows="10" required id="id_content"></textarea></td></tr>
# forms.py

from django import forms

class PostForm(forms.Form):
    title = forms.CharField()
    content = forms.CharField(widget=forms.Textarea)

forms.Form 은 필드를 직접 지정해줘야하고 forms.ModelForm 은 모델에 필드로 지정해줄 수 있습니다.

# views.py

from django.shortcuts import render,redirect
from .forms import PostForm

def home(request):
    return render(request, "core/home.html")

def post_create(request):
    if request.method == "POST":
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = Post(**form.cleaned_data)
            post.save()
            return redirect('home')
    else:
        form = PostForm()
    context = {
        'form' : form
    }
    return render(request, 'core/post_create.html', context)

현재 forms. 에서 forms.Form 을 사용하고 있지만 forms.ModelForm 을 사용한다면 views 를 다음과 같이 바꿀 수 있습니다.

if form.is_valid():
    post = form.save()
    return redirect('home')

validation, 유효성 검사

validationforms 에서도 가능하지만 models 내에서 하는걸 더 추천합니다.

우선 validation을 사용하기 위해서 기존에 작성했던 formsModelForm 을 사용해서 다시 작성해보겠습니다.

# forms.py
from django import forms
from . models import Post

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = '__all__'

이제 models 에서 validation을 지정해주도록 합시다.

# models.py
from django.db import models
from django.core.validators import MinLengthValidator

title_validator = MinLengthValidator(3, "길이가 너무 짧습니다.")

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=10, validators=[title_validator])
    content = models.TextField()

MinLengthValidator 은 django 에서 지원해주는 validation 으로 최소 길이와 오류 메세지를 지정해줄 수 있습니다.