웹을 만들면서 귀찮은 일 중의 하나가 form이다. 입력 폼을 구성하고 디자인을 맞추고, 또한 필요하다면 front-end에서 체크할 수 있게 javascript도 짜게 될 수도 있다. back-end에서 값을 받아서 처리하는 일도 해야한다. 개인적으로 서버 로직 짜는 건 괜찮은데 보이는 쪽을 만지는 것은 꽤나 귀찮은 일이다. 다행히 django에서는 form에 관한 사항을 일괄적으로 다루기 때문에 많은 도움이 되기는 커녕 front-end쪽을 건드리는 것은 아니기 때문에 여전히 내가 하기 싫은 일은 남아있다. 초심자라면 더욱이 난감한 상황이 발생할 수 있다. 우선 django에서 다음의 간단한 form을 쓰겠다 (폼 필드를 일일이 쓰기 싫어서 ModelForm을 씀을 양해부탁드립니다).

# myapp/forms.py
from django import forms
from myapp.models import MyModel

class MyForm( forms.ModelForm ):
    class Meta:
        model = MyModel

이 폼은 MyModel이 갖고 있는 필드들을 알아서 속성과 함께 끌고 들어온다. 이 폼을 html에 뿌리기 위한 view를 이렇게 작성하겠다

# myapp/views.py
from django.shortcuts import render
from myapp.forms import MyForm

def my_view( request ):
    if request.method == 'POST':
        # 입력 받아서 처리하는 부분...

    context = { 'form' : MyForm( ) }

    return render( request, 'myapp/template.html', context )

그리고 템플릿 html파일에서 form을 넣는 부분이 이렇게 될 것이다.

# myapp/template.html

<form action="{% url %}" method="post">
    {{ form }} 또는
    {{ form.as_p }} 또는
    {{ form.as_table }} 또는
    {{ form.field_name }} 필드를 각각 입력할 수도 있다.
</form>

문제는 무엇일까. django가 context variable {{ form }} 을 통해 html에 넘기는데 ... 스타일이나 클래스를 줄 수가 없다. django-widget-tweaks 라는 외부 모듈을 이용해서 문제를 해결하는 길이 있긴 하지만 django안에서 해결할 수 있으면 그 방법을 쓰는 것이 나는 더 좋아서 django가 form에 html 속성을 붙이는 방법을 정리하겠다.

# myapp/forms.py

class MyForm( forms.ModelForm ):
  class Meta:
    model = MyModel

    def __init__( self, *args, **kwargs ):
        super( MyForm, self ).__init__( *args, **kwargs )
        self.field[ 'my_field' ].widget.attrs.update( {
            'class': 'form-control',
            'id': 'form-id',
            'placeholder': 'Do not use numbers.' } )

django는 form field에 따라 다양한 widget을 제공한다. 예를 들어 forms.CharField를 쓴다면 기본값으로 forms.TextInput을 widget으로 제공하는데, 이것은 실제로 <input type="text"/>와 같은 것이다. 따라서 위의 코드는 각 폼 필드에 따라 기존에 쓰이고 있는 widget의 속성(attributions;attrs)을 업데이트한다고 생각하면 될 것이다.




참조

django docs: form widget에 대한 공식 문서
https://docs.djangoproject.com/en/1.9/ref/forms/widgets/

django docs: form에 대한 전반적 정보를 알려주는데 찬찬히 읽어보면 꽤 도움이 된다.
https://docs.djangoproject.com/en/1.9/topics/forms/