본문 바로가기
Web Backend/Django

[Django] Django 학습 정리 - Django Form

by 요호유후 2025. 3. 29.
반응형

지금까지 Django 학습한 내용을 바탕으로 정리를 해보려 한다.

 

목차
Form
  1. 역할
  2. 종류 및 생성
  3. widgets
  4. Django 기본 제공 폼 (CreationForm, AuthenticationForm)
  5. 데이터 유효성 검사 (is_valid())
  6. 폼 출력 시퀀스
[작업 환경]
MacOS, PyCharm
pyenv, poetry
Python, Django

 

 

Form

1.  Form 역할

- 사용자에게 보여질 입력 폼(UI)을 정의하는 클래스이다.
- 예를 들어 댓글 작성, 게시글 작성 같은 입력 영역이 Form에 해당된다.

 

2. Form 종류 및 생성

    ⭐️ forms.Forms (기본 폼)

- 단순한 입력 폼을 정의할 때 사용한다.

        📌 사용예)

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(max_length=100)
    message = forms.CharField(widget=forms.Textarea)

 

    ⭐️ forms.ModelForm (DB 필드 기반 폼)

- 모델과 연결된 폼을 정의할 때 사용한다. 

        📌 사용예)

from django import forms

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('content',)

   

    ⭐️ BootstrapModelForm (예쁜? 폼)

- 커스터마이징한 ModelForm 이다.
- Bootstrap의 CSS 클래스를 자동 적용해서 폼을 예쁘게 한 것이다.

        📌 사용예)

from utils.forms import BootstrapModelForm

class PostForm(BootstrapModelForm):
    class Meta:
        model = Post
        fields = ('content', )

 

# utils/forms.py

from django import forms

class BootstrapModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for name, field in self.fields.items():
            if 'class' in field.widget.attrs:
                field.widget.attrs['class'] += ' form-control'
            else:
                field.widget.attrs.update({'class': 'form-control'})

            if isinstance(field.widget, forms.Textarea):
                field.widget.attrs.update({'rows': 4})

 

3. widgets (위젯)

- .html 입력 필드의 형태를 지정할 때 사용한다.

        📌 사용예)

class BlogPostForm(forms.ModelForm):
    class Meta:
        model = Blog
        # fields = '__all__' # 전부 가져오고 싶을 때
        fields = ('category', 'title', 'image', 'content')
        widgets = {
            'content': SummernoteWidget()  # Rich text editor 사용
        }
        
 class CommentForm(forms.ModelForm):
    class Meta:
        model = Comment
        fields = ('content',)
        widgets = {
            'content': forms.TextInput(attrs={'class': 'form-control'})
        }

 

    ⭐️ Django 위젯 및 주요 attrs 정리

위젯 설명 attrs 비고
TextInput 한 줄 텍스트 입력 class, placeholder, maxlength 기본 텍스트 입력
Textarea 여러 줄 텍스트 입력 rows, clos, placeholder, class 게시글, 코멘트 등
PasswordInput 비밀번호 입력 class, placeholder 입력값 숨김 처리
EmailInput 이메일 전용 입력 class, placeholder, type 자동 유효성 검사 적용 가능
DateInput 날짜 입력 type='data', class -
FileInput 파일 업로드 필드 class, accept 이미지, 문서 등 첨부
Select 단일 선택 드롭다운 class choices 옵션 필요
CheckboxInput 체크박스 class, checked BooleanField와 함께 사용

 

4. Django 기본 제공 Form

    ⭐️ UserCreationForm

- Django에서 기본 제공하는 회원가입 폼 이다.
- username, password1, password2 필드를 기본으로 가진다.
- is_valid()로 두 비밀번호(password1, password2) 일치 여부 등 자동 검증 할 수 있다.

        📌 사용예1)

# forms.py 작성

from django.contrib.auth.forms import UserCreationForm

class SignupForm(UserCreationForm):
    pass  # 커스터마이징 가능

        📌 사용예2)

# views.py 작성

def sign_up(request):
    form = UserCreationForm(request.POST or None) # POST 이거나 get(아무것도 안 넣어줘도 되는 것)

    if form.is_valid():
        form.save()
        return redirect(settings.LOGIN_URL)
        
    context = {
        'form': form
    }

    return render(request, 'registration/signup.html', context)

 

    ⭐️ AuthenticationForm

- Django에서 기본 제공하는 로그인 폼 이다.
- username, password 필드를 기본으로 가진다.
- 유효성 검사(is_valid())를 통해 로그인 처리가 가능하다.

        📌 사용예)

def login(request):
    form = AuthenticationForm(request, request.POST or None)

    if form.is_valid():
        django_login(request, form.get_user())

        next = request.GET.get('next')
        if next:
            return redirect(next)

        return redirect(reverse('blog:list'))

    context = {'form': form}

    return render(request, 'registration/login.html', context)

 

5. 데이터 유효성 검사

form.is_valid() : 폼에서 전달받은 데이터가 유효한지 확인하는 메소드
  - 필수 필드 확인
  - 형식 오류 확인
  - clean_ 메소드가 있으면 그걸 통해 사용자 정의 검증도 수행

        📌 사용예)

def login(request):
    form = AuthenticationForm(request, request.POST or None)

    if form.is_valid():
        django_login(request, form.get_user())

        next = request.GET.get('next')
        if next:
            return redirect(next)

        return redirect(reverse('blog:list'))

    context = {'form': form}

    return render(request, 'registration/login.html', context)

 

6. 폼 출력 시퀀스

- 뷰(View) → 폼(Form) → 템플릿(Template)의 연결 흐름을 가진다.    

 

    ⭐️ 연결 흐름

# 1. 폼 인스턴스 생성 및 context에 담아서 템플릿에 전달

class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    template_name = 'post/form.html'
    form_class = PostForm  # 자동으로 context['form']에 넣어 줌
    
class PostListView(ListView):
    queryset = Post.objects.all().select_related('user').prefetch_related('images', 'comments', 'likes')
    template_name = 'post/list.html'
    paginate_by = 5
    ordering = ('-created_at', )

    def get_context_data(self, *args, **kwargs):
        data = super().get_context_data(*args, **kwargs)
        data['comment_form'] = CommentForm() # 직접 정의(폼 여러 개, 조건 분기 등의 상황에서는 직접 정의함)
        return data

 

# 2. .html에서 {{ form }} 혹은 {{form.as_p }} 형태로 랜더링

{% extends 'base.html' %}
{% load static %}

{% block content %}
  <div class="row">
    <div class="col-10 offset-1 col-lg-6 offset-lg-3">
      <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}  # 폼 랜더링

        <table class="table">
          {{ formset.management_form }}
          <thead>
          ...

 

 

 

 

반응형

댓글