Developer's Development

3.4.8 [Django] Form 처리 본문

AI 활용 애플리케이션 개발/Django Framework

3.4.8 [Django] Form 처리

mylee 2025. 10. 19. 23:04
폼(Form)

 

Django의 폼은 HTML 폼을 생성하고, 사용자 입력 데이터를 유효성 검사를 통해 처리하는 도구이다. 수동으로 HTML 코드를 작성할 필요 없이, 파이썬 코드로 폼을 정의할 수 있다.

 

  • 폼 생성

1. 폼 클래스 정의 (forms.py)

2. 뷰에서 폼 사용 (views.py)

3. 템플릿에서 폼 렌더링

 

  • 모델 폼

모델 폼은 모델과 연결된 폼으로, 모델의 필드와 데이터 검증을 자동으로 처리한다.

1. 모델 폼 정의 (forms.py)

2. 뷰에서 모델 폼 사용

 

메시지 프레임워크

 

Django의 메시지 프레임워크를 사용하면 사용자에게 알림 메시지를 전달할 수 있다. 메시지는 성공, 경고, 오류 등의 유형으로 분류된다.

 

  • 메시지 프레임워크 설정

1. 메시지 추가 (views.py)

2. 템플릿에서 메시지 표시

 

  • 메시지 유형

기본 메시지 유형

: messages.debug, messages.info. messages.success, messages.warning, messages.error

 

👉🏻 프로젝트 및 앱 생성

django-admn startproject _04_django_form
cd _04_django_form
django-admin startapp main

 

👉🏻 settings.py 수정

앱 등록 및 데이터베이스 설정

# 수정
INSTALLED_APPS = [
    'django.contrib.admin',
    ...
    'main'	# 방금 만들어준 앱 등록
]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'djangodb',
        'USER': 'django',
        'PASSWORD': 'django',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

# 추가
STATIC_URL = 'static/'

MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

 

👉🏻 모델 정의

main/models.py 수정

from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    price = models.PositiveIntegerField()

    def __str__(self):
        return self.title
    
class Document(models.Model):
    title = models.CharField(max_length=100)
    file = models.FileField(upload_to='documents/')

 

👉🏻 main/migrations/0001_initial.py

from django.db import migrations, models

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='Book',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=100)),
                ('author', models.CharField(max_length=100)),
                ('published_date', models.DateField()),
                ('price', models.PositiveIntegerField()),
            ],
        ),
    ]

 

👉🏻 main/migrations/0002_document.py

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('main', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='Document',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=100)),
                ('file', models.FileField(upload_to='documents/')),
            ],
        ),
    ]

 

👉🏻 데이터베이스 반영

마이그레이션 파일 생성 및 데이터베이스에 적용

python manage.py migrations
python manage.py migrate

 

👉🏻 projects/urls.py 수정

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('main.urls')),
]

 

👉🏻 main/urls.py 추가

from django.urls import path
from main import views
from .views import BookListView, BookDetailView, BookCreateView

app_name = 'main'

urlpatterns = [
    path('contact/', views.contact_view, name='contact'),
    path('book/', views.create_book_view, name='book'),
    path('upload/', views.upload_view, name='upload'),
]

 

👉🏻 main/forms.py 추가

from django import forms
from .models import Book, Document

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

class BookForm(forms.ModelForm):
    class Meta:
        model = Book
        fields = ['title', 'author', 'published_date', 'price']

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ['title', 'file']

 

👉🏻 main/views.py 수정

from django.shortcuts import render, redirect
from .forms import ContactForm, BookForm, DocumentForm
from django.contrib import messages
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy

def contact_view(request):
    form = ContactForm(request.POST or None)
    if form.is_valid():
        print(form.cleaned_data['name'])
        print(form.cleaned_data['email'])
        print(form.cleaned_data['message'])
        messages.success(request, '연락처 정보 전송 완료!')
        return redirect('main:contact')
    return render(request, 'contact.html', {'form': form})

def create_book_view(request):
    form = BookForm(request.POST or None)
    if form.is_valid():
        form.save()
        messages.success(request, '도서 정보 등록 완료!')
        return redirect('main:book')
    return render(request, 'book_form.html', {'form': form})

def upload_view(request):
    form = DocumentForm(request.POST or None, request.FILES or None)
    # print(request.POST)
    # print(request.FILES)
    if form.is_valid():
        form.save()
        messages.success(request, '파일 업로드 완료!')
        return redirect('main:upload')
    return render(request, 'upload.html', {'form': form})

 

👉🏻 main/templates에 템플릿 html 추가

book_form.html

{% if messages %}
<ul>
    {% for message in messages %}
        <li>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">전송</button>
</form>

 

contact.html

{% if messages %}
<ul>
    {% for message in messages %}
        <li>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">전송</button>
</form>

 

upload.html

{% if messages %}
<ul>
    {% for message in messages %}
        <li>{{ message }}</li>
    {% endfor %}
</ul>
{% endif %}

<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">전송</button>
</form>