[Django +] Form 클래스를 사용한 뷰와 템플릿 파일

MINJEE·2023년 12월 15일

SMHRD_7_Django

목록 보기
6/8
post-thumbnail

폼(Form) 클래스는 페이지 요청 시 전달되는 파라미터들을 쉽게 관리하기 위해 사용하는 클래스입니다.

Form 클래스를 정의하면
템플릿 파일에 폼을 작성할 때 더 간단하게 작성할 수 있습니다.
또한 views.py 파일의 코드도 더욱 간결해집니다.

모델과 폼을 사용하여 작성한 ORM방식의 CRUD 구현을 했습니다.

모델 정의

app2/models.py

# app2/models.py

from django.db import models

class Song(models.Model):
    title = models.CharField(max_length=50) # 노래 제목
    singer = models.CharField(max_length=50) # 가수
    date = models.DateTimeField(auto_now = True) # 내가 등록한 날
    score = models.IntegerField() # 내가 준 별점

    def __str__(self):
        return self.title

폼 정의

폼을 정의하기 위해서는 앱 내에 forms.py 파일이 자동으로 생성되지 않기 때문에 따로 생성해야 합니다.
app2/forms.py

# app2/forms.py

from django import forms
from app2.models import Song

class SongForm(forms.ModelForm):
    class Meta:
        model = Song
        fields = ['title', 'singer', 'score'] # 폼에서 사용할 모델 클래스의 속성명
        labels = {'title':'노래 제목', 'singer':'가수', 'score':'별점'} # 폼에서 각 속성을 표시할 문자열
  • 장고의 forms.ModelForm 클래스를 상속받아 폼 클래스를 정의
    • 모델의 속성을 폼 필드로 사용 가능
  • Meta 클래스는 폼 클래스의 내부 클래스로서, 폼의 메타데이터를 정의
    • model = 모델명 : model은 폼이 사용할 모델을 지정
    • fields = ['속성1', '속성2', ...] : fields는 폼에서 사용할 모델의 속성을 지정하는 리스트
    • labels = {'속성1': '표시값1', '속성2': '표시값2', ...} : labels는 폼에서 각 속성을 표시할 때 사용할 문자열을 지정하는 딕셔너리

URL 매핑

모델과 폼을 정의했다면, url과 뷰를 매핑하는 작업을 한다.
app2/urls.py

# app2/urls.py

from django.urls import path
from . import views

app_name = 'app2' # 앱 이름 등록

urlpatterns = [
    ################# 2. ORM 방식(객체-관계 매핑) #################
    path('songs/', views.ormList, name='orm-list'),
 	path('songs/<int:pk>/', views.ormDetail, name='orm-detail'),
 	path('songs/create/', views.ormCreate, name='orm-create'),
 	path('songs/<int:pk>/update/', views.ormUpdate, name='orm-update'),
 	path('songs/<int:pk>/delete/', views.ormDelete, name='orm-delete'),
]
  • urls.py 파일은 폼 없이 모델만 사용했을 때와 동일하다.

app2/views.py

# app2/views.py

from .models import Song
from django.shortcuts import render, redirect
from .forms import SongForm

def ormList(request):
    dataList = Song.objects.all() # 모든 요소 가져오기
    return render(request, "app2/song_list.html", {'songs':dataList})

def ormDetail(request, pk):
    data = Song.objects.get(id=pk)
    return render(request, 'app2/song_detail.html', {'song': data})
     
def ormCreate(request):
    if request.method == 'POST':
        form = SongForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('app2:orm-list')
    else:
        form = SongForm()
        success_url = '/app2/songs/create/'
        return render(request, 'app2/song_create.html', {'form': form, 'success_url':success_url})

def ormUpdate(request, pk):
    if request.method == 'POST':
        form = SongForm(request.POST, instance=data)
        if form.is_valid():
            form.save()
            return redirect('app2:orm-detail', pk=pk)
    else:
        form = SongForm(instance=data)
        success_url = f'/app2/songs/{pk}/update/'
        return render(request, 'app2/song_update.html', {'form': form, 'song': data, 'success_url':success_url})
        
def ormDelete(request, pk):
    data = Song.objects.get(id=pk)
    if request.method == 'POST':
        data.delete()
        return redirect('app2:orm-list')
    success_url = f'/app2/songs/{pk}/delete/'
    return render(request, 'app2/song_confirm_delete.html', {'song': data, 'success_url':success_url})
  • views.py 파일은 폼 클래스를 사용함으로써, 데이터 생성과 수정 관련 뷰 함수의 코드가 간단해진 것을 확인할 수 있다.
  • SongForm(request.POST) : 요청 메서드가 POST인 경우, SongForm을 생성하고 전달된 데이터를 폼에 바인딩
  • SongForm(request.POST, instance=data) : instance 매개변수를 사용하여 수정 대상 데이터를 지정
  • form.is_valid() : 폼 데이터의 유효성 검사를 통해 폼이 올바른 형식인지 확인
  • form.save() : 폼 데이터를 데이터베이스에 저장
  • SongForm() : 요청 메서드가 POST가 아닌 경우, 빈 SongForm을 생성하여 폼을 초기화
  • SongForm(instance=data) : 요청 메서드가 POST가 아닌 경우, 기존 데이터를 가져와서 SongForm을 생성하고 폼을 초기화

생성, 수정 폼 템플릿 파일

templates/app2/song_create.html

<!-- templates/app2/song_create.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>노래 별점 매기기</h1>
  <form method="post" action="{{success_url}}"> 
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">등록</button>
  </form>
</body>
</html>
  • 데이터 목록 페이지 :
  • 추가 버튼 → 데이터 생성 페이지 :
    • 생성 폼의 {{ form.as_p }}
      : form 은 views.py 에서 SongForm()가 담긴 변수,
      폼 객체의 as_p 메서드는 폼 필드들을 <p> 태그로 감싸서 텍스트 형태로 표시해주는 기능

templates/app2/song_update.html

<!-- templates/app2/song_update.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>노래 수정하기</h1>
  <form method="post" action="{{success_url}}"> 
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">수정</button>
  </form>
</body>
</html>
  • 노래제목 → 데이터 상세 페이지 :
  • 수정 버튼 -> 데이터 수정 페이지 :
    • 수정 폼의 {{ form.as_p }}
      : form 은 views.py 에서 SongForm(instance=data)가 담긴 변수로, form객체는 수정하기 위한 데이터의 원래 속성값을 가지고 있고,
      폼 객체의 as_p 메서드는 폼 필드들을 <p> 태그로 감싸서 텍스트 형태로 표시해주고, 데이터의 원래 속성값을 입력 필드 들의 'value' 속성으로 표시해주는 기능

{{ form객체.as_table }}, {{ form객체.as_ul }} 등의 메서드도 있으며,
각각 테이블 형태(<table>)와 리스트 형태(<ul>)로 폼을 표시

profile
개발, 분석 배운 내용 정리하기!

0개의 댓글