반응형

안녕하세요.

장고의 폼 사용법에 대해서 학습을 하도록 하겠습니다.

 

장고를 활용하여 웹사이트를 만들 때 사용자에게 보여주는 기능만 제공하는 웹사이트를 만드시는 것이 아니라면, 사용자가 데이터도 입력을 할 수 있어야 됩니다.

장고는 입력에 대한 처리를 할 수 있도록 폼 기능을 제공해줍니다.

 

HTML에서 form이란  <form> ... </form> 태그 내에서 우리의 웹사이트를 사용하는 사용자가 데이터를 입력할 수 있도록 하고 서버로 데이터를 보내주는 역할을 제공합니다.

폼은 2가지의 정보를 담고 있어야 되는데요. 서버로 보낼 때 어디로 보낼지 그리고 HTTP 방법을 명시해줘야 됩니다. 데이터를 보낼 때, HTTP 방법은 POST 방식으로 보내기 되어 POST를 입력을 해줄 겁니다.

아래의 submit type이 트리거가 되어 사용자가 Log in 버튼을 누르면 데이터가 전송이 되는 것이죠.

<input type="submit" value="Log in">

 

장고에서 폼이란?

폼을 핸들링하는 것은 생각보다 복잡합니다. 사용자를 위해서 수많은 타입의 데이터 항목들이 필요로 하고 화면에 보여줘야 되며 이런 값들은 다시 서버로 보내집니다. 이후에도 값들에 대한 유효성 검증이 필요로 하죠. 검증 이후에는 데이터를 처리하는 로직까지도 필요로 합니다. 

장고에서는 이런 작업들에 대해서 단순화시켜주고 자동화 기능을 제공해줍니다. 또한 개발자가 HTML 작성을 하여 폼 관련 핸들링하는 코드를 작성하는 것보다 장고에서 제공하는 폼 기능이 더욱 보안적 요소가 훌륭합니다.

 

포괄적으로 장고 폼 기능은 다음 3가지로 요약할 수 있습니다.

  • 렌더링을 위해서 데이터를 준비하고 재구성을 해줍니다.
  • HTML 폼을 만들어줍니다.
  • 클라이언트로부터 제출이 된 데이터를 받고 처리해줍니다.

HTML의 form 태그는 폼 역할의 단지 한 부분의 불과합니다. 하지만 장고에서의 폼 개념은 위에서 설명드린 기능들을 제공합니다. 이런 기능들을 사용하기 위해서 Form Class를 사용해주시면 되는데요.

모델 클래스의 필드는 모델 클래스의 필드가 데이터베이스 필드에 매칭 되는 것처럼, 폼도 폼 필드의 클래스는 html 요소 즉 태그에 매핑이 됩니다. 폼이 제출되면 유효성 검사까지 수행이 됩니다.

 

장고에서 폼을 사용하기

이제는 장고에서 폼을 어떻게 사용하는지 코드를 작성하며 살펴보도록 하겠습니다.

사용자 이름을 받는 웹사이트가 있다고 생각을 해보겠습니다.

<form action="{% url 'myform:index' %}" method="post">
    <label for="your_name">Your name: </label>
    <input id="your_name" type="text" name="your_name" value="{{ current_name }}">
    <input type="submit" value="OK">
</form>

이름을 입력받을 때 text input과 submit input이 있습니다. 유저로부터 받은 데이터는 myform:index 위치로 전송되고 HTTP 방식은 POST입니다. 우리가 많이 봐 오던 폼 형태입니다.

예제에서는 예시 코드로 코드 내용이 그리 많지 않으나 실제로는 폼 관련 코드가 복잡하고 양이 많을 겁니다.

그중 많은 필드는 미리 데이터가 작성이 되어 있어야 되고 유효성 검사도 필요로 합니다.

이쯤 되면 장고에서의 폼 기능을 필요로 합니다.

 

forms.py

from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name name', max_length=7)

우리는 위에서 작성한 HTML 모습의 폼 모양이 필요로 하는 것을 필요로 하는데, 그 점이 폼을 작성하기 위한 시작점입니다.

forms 코드를 보시게 되면 charField를 갖는 your_name 폼을 하나 갖고 있습니다. you_name의 최대 길이는 7로 제한(값 유효성 확인 가능)을 뒀으며 label 명도 직접 설정을 할 수 있습니다. 이상 폼 코드를 작성한 내용입니다.

위의 작성한 코드를 사용해서 화면에 rendering 하기도 하고 값을 받아와서 처리를 하는 것입니다. form html 코드를 작성하지 않고 말이죠.

 

Form 인스턴스는 is_valid() 함수를 갖고 있습니다. is_valid() 함수는 입력받은 폼의 대한 유효성 검사를 실행합니다. is_valid() 함수가 호출되면 값이 유효하다면 참이 리턴되고 cleaned_data에 값이 저장이 됩니다. 이 내용은 뷰 로직에서 다뤄지니 뷰 코드에서 다시 보도록 하겠습니다. 지금은 값이 유효하다면 참이 리턴되고 cleaned_data에 저장이 되는 것을 명심해주시면 됩니다.

 

뷰에서 작성한 폼을 사용하도록 하겠습니다.

views.py

from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm

def index(request):
    # if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = NameForm(request.POST)

        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            # ...
            # redirect to a new URL:
            return HttpResponseRedirect('/myform/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = NameForm()

    return render(request, 'myform/name.html', {'form': form})

def thanks(request):
    return render(request, 'myform/thanks.html')

GET 요청이 들어왔다면 NameForm()을 통해서 비어 있는 폼을 사용자 화면에 보여 줄 것입니다.

POST 요청이 들어온다면 NameForm(request.POST)을 통해서 요청으로부터 받은 데이터와 폼을 묶어(바인딩) 줍니다. form.is_valid()를 통해서 유효성 검사를 하는 겁니다. 앞서 설명드린 바와 같이 유효하다면 참이 리턴되어 thanks 페이지로 이동하고 그렇지 않다면 다시 이름 입력 페이지가 보이게 됩니다.

참이 될 때는 cleaned_data에 유효한 데이터는 모두 저장이 됩니다. cleaned_data는 어떻게 사용이 되는지 잠시 후에 보도록 하겠습니다.

 

뷰 로직까지 작성을 했으니 템플릿에서 어떻게 장고 폼 관련에 처리를 하는지 보겠습니다.

name.html

<form action="{% url 'myform:index' %}" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="OK">
</form>

GET 요청이 들어왔을 때 form을 context에 담아서 템플릿에 보냈습니다. 그럼 템플릿에서는 {{ form }}을 작성을 해주시면 장고 forms.py에서 작성한 form관련 모습을 보실 수 있습니다.

위에서 html을 직접 작성한 모습과 동일한 모습입니다. 레이블 모습은 구분을 위해서 name을 하나 더 추가하였습니다. 눈여겨볼 것은 문자의 최대길이를 7자리로 제한을 뒀기 때문에 7자리 이상은 입력이 되지 않습니다.

 

여기까지가 form 사용에 기본적인 방법입니다. 지금은 input이 하나이기 때문에 조금 더 복잡해 보일 수 있으나 입력받는 값이 많거나 데이터베이스에 값을 저장한다거나 할 때는 장고 폼의 위력이 대단합니다.

 

cleaned_data 사용하는 예제를 보기 위해서 조금 더 복잡한 예제를 보겠습니다.

forms.py

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)
    sender = forms.EmailField()
    cc_myself = forms.BooleanField(required=False)

NameForm과 달리 데이터 타입이 늘어났습니다.

폼이 늘어 나도 사용방법은 동일합니다 :)

 

views.py

if form.is_valid():
    subject = form.cleaned_data['subject']
    message = form.cleaned_data['message']
    sender = form.cleaned_data['sender']
    cc_myself = form.cleaned_data['cc_myself']

    recipients = ['info@example.com']
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect('/thanks/')

is_valid()를 통해서 유효성 검사 이후에 필요에 따라서 cleaned_data에 저장된 데이터를 갖고 오는 겁니다. 그리고 메일 발송 로직을 추가해준 코드입니다.

 

이상으로 폼의 대한 개념과 사용방법에 대해서 학습을 했습니다.

위의 내용은 기본 기능들에 대한 설명이고 장고 폼은 더욱 많은 기능을 담고 있습니다. 내용이 조금 더 필요하시다면 아래의 문서를 읽어 보시고 폼을 조금 더 잘 활용하시면 좋겠습니다.

https://docs.djangoproject.com/en/3.0/topics/forms/

 

감사합니다 :)

반응형

+ Recent posts