Django 폼 (Form)

1. Django 폼 (Form)

Django 프레임워크는 Model 클래스로부터 폼(Form)을 자동으로 생성하는 기능을 제공하고 있다. 모델 클래스로부터 폼 클래스를 만들기 위해서는,
(1) django.forms.ModelForm 클래스으로부터 파생된 사용자 폼 클래스를 정의한다.
(2) 사용자 폼 클래스 안에 Meta 클래스 (Inner 클래스)를 정의하고 Meta 클래스 안 model 속성(attribute)에 해당 모델 클래스를 지정한다. 즉, 어떤 모델을 기반으로 폼을 작성할 것인지를 Meta.model 에 지정하는 것이다.

앞에서 정의하였지만, 다시 한번 Model 클래스를 삺펴보면 다음과 같다. (./feedback/models.py)

from django.db import models

class Feedback(models.Model):
     name = models.CharField(max_length=100)
     email = models.EmailField()
     comment = models.TextField(null=True)
     createDate = models.DateTimeField(auto_now_add=True)

위의 Feedback 모델 클래스에 기반하여 폼 클래스를 만들기 위해 ./feedback/forms.py 를 만들고 아래와 같이 폼 클래스 "FeedbackFrom"를 정의한다. FeedbackFrom 클래스는 ModelForm로부터 파생된 클래스이며, Meta 안의 model 속성에 "models.Feedback" 모델 클래스를 지정하였다. fields는 모델 클래스의 필드들 중 일부만 폼 클래스에서 사용하고자 할 때 지정하는 옵션으로, 여기서는 createDate를 뺀 나머지 필드들만 사용하도록 정의하였다.

from django.forms import ModelForm
from .models import Feedback

class FeedbackFrom(ModelForm):
    class Meta:
        model = Feedback
        fields = ['id', 'name','email','comment']

이렇게 사용자 폼이 정의되었으면, View와 템플릿에서 이 폼을 사용하게 된다. 아래는 ./feedback/views.py 에 추가된 함수로서 새로운 Feedback 데이타를 추가하기 위한 폼을 핸들링하는 함수이다.

from django.shortcuts import render, redirect
from .models import *
from .forms import FeedbackFrom

def create(request):
    if request.method=='POST':
        form = FeedbackFrom(request.POST)
        if form.is_valid():
            form.save()
        return redirect('/feedback/list')
    else:
        form = FeedbackFrom()

    return render(request, 'feedback.html', {'form': form})

위의 함수는 크게 두 부분으로 나눌 수 있는데, (1) 데이타를 입력 받는 폼을 보여 주는 부분과 (2) 사용자가 데이타를 입력하여 저장버튼을 눌렀을 때 이를 DB에 저장하는 부분이다.
우선 데이타를 입력 받는 폼은 POST 가 아닌 부분(즉 else 부분)과 마지막 render 부분으로 입력 부분만 발췌하면 아래과 같다. render()의 첫번째 파라미터는 request를 지정하고, 두번째는 사용할 템플릿 파일을 지정하며, 세번째 파라미터는 템플릿에 전달한 데이타 혹은 객체들을 (흔히 컨텍스트라고 함) 지정한다. 컨텍스트는 Dictionary로 전달하는데, 여기서는 "form" 이라는 키에 FeedbackFrom() 빈 객체값을 할당하여 전달하고 있다.

def create(request):
    form = FeedbackFrom()
    return render(request, 'feedback.html', {'form': form})

위에서 호출하는 템플릿 (./feedback/templates/feedback.html) 예제를 살펴보면 아래와 같다. 아래 템플릿에서 주목할 부분은 View 에서 전달한 "form" 객체를 템플릿 변수로 사용하고 있는 부분이다. 아래 예제에선 {{ form.as_p }} 와 같이 폼을 <p> HTML를 사용하여 랜더링하도록 하고 있다 (form.as_p는 폼의 각 필드를 p 태그 안에서 레이블과 텍스트로 배치한다). 폼을 랜더링하는 옵션으로 form, form.as_p, form.as_table, form.as_ul 등이 있는데, 이 옵션은 각 필드를 어떤 HTML 태그로 Wrapping 할 것인가를 지정하는 것이다.

{% extends "base.html" %}

{% block content %}
    <p>
        <a href="{% url 'list' %}">Goto Feedback List</a>
    </p>

    <div>
        <form method="POST">
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit">저장</button>
        </form>
   </div>

{% endblock content %}

위의 템플릿에서 한가지 더 언급할 만한 점은 HTML FORM 안에 {% csrf_token %} 를 넣어 준 것이다. CSRF (Cross Site Request Forgeries)는 웹 해킹 기법의 하나로 Django는 이를 방지하기 위한 기능을 기본적으로 제공하고 있다. Django에서 HTTP POST, PUT, DELETE을 할 경우 이 태그를 넣어 주어야 한다.

그러면 마지막으로 사용자가 데이타를 입력하고 저장 버튼을 눌렀을 때, 데이타를 저장하는 부분을 살펴보자. 위의 views.py 에 있는 코드 중 request.method 가 POST 인 부분이 저장부분에 해당된다. 아래 부분 발췌된 코드르 보면, 저장 버튼이 눌려저 HTTP POST가 전달되면, 사용자 정의 폼 FeedbackFrom() 생성자의 파라미터로 포스트 데이타 (주: request.POST는 Dictionary로서 포스트된 데이타를 갖고 있다)를 패스하여 폼 객체를 생성한다. 이 싯점에 이 FeedbackFrom 객체는 POST로부터 전달된 데이타를 객체의 필드에 갖게 된다. 이어 is_valid() 매서드를 사용하여 POST 데이타에 잘못된 데이타가 전달되었는지를 체크하고, 만약 정상이면 save() 메서드를 호출하여 DB에 데이타를 저장한다. 저장후 여기서는 list 뷰 (다음 아티클 참조)로 이동하도록 코딩하였다.

def create(request):
    if request.method=='POST':
        form = FeedbackFrom(request.POST)
        if form.is_valid():
            form.save()
        return redirect('/feedback/list')
    #.....
본 웹사이트는 광고를 포함하고 있습니다. 광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.