장고(django)의 폼(Form)

2019-06-03

장고(django)의 폼(Form)을 이용하여 데이터를 추가하거나 수정하는 방법에 대해서 알아보겠습니다.

개요

지금까지는 장고(django)가 기본적으로 제공하는 관리자 페이지(Administrator)를 사용하여 데이터를 추가하거나 수정하였습니다. 이번 블로그에서는 장고(django)의 폼(Form)을 이용하여 데이터를 추가하거나 수정하는 방법에 대해서 알아보도록 하겠습니다.

이 블로그는 시리즈로 작성되어 있으며, 아래에 링크를 통해 시리즈의 다른 글을 확인할 수 있습니다.

이 블로그는 시리즈로 작성되어 있으며, 아래에 링크를 통해 시리즈의 다른 글을 확인할 수 있습니다.

또한 이 블로그 시리즈에서 다룬 소스는 github에 공개되어 있습니다. 아래에 링크를 통해 확인 가능합니다.

폼(Form) 생성

장고(django)의 폼(Form) 기능을 사용하기 위해서 blog/forms.py 파일을 생성하고 아래와 같이 수정합니다.

from django import forms
from .models import Post

class PostCreateForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'content')
  • from django import forms: 장고(django)가 기본적으로 제공하는 폼(form)을 불러옵니다.
  • from .models import Post: 폼(Form)을 통해 데이터를 추가하거나 수정할 Post 모델(Model)을 불러옵니다.
  • class PostCreateForm(forms.ModelForm):: PostCreateForm이라는 이름으로 클래스를 생성하고 fomrs.ModelForm을 상속받습니다.
  • class Meta:: 이 폼(Form)에서 다룰 내용을 작성합니다. 여기에서는 이 폼(Form)이 다룰 모델(Model)이 Post임을 알려줬고(model = Post), 그 중에서 title과 content 필드(fields = ('title', 'content'))를 다룰 것임을 알려주었습니다.

뷰(View) 생성

이제 장고(django)의 폼(Form)을 사용할 뷰(View)를 작성해야 합니다. 뷰(View) 작성은 이전 블로그(장고(django)의 뷰(View))에서 연습하였기 때문에 좀 더 쉽게 제작할 수 있을거 같습니다.

HTML 파일 생성

일단 데이터를 입력 받을 웹 페이지를 작성해 봅니다. blog/templates/post_create.html 파일을 생성하고 아래와 같이 수정합니다.


{% extends 'blog/layout.html' %}

{% block content %}
    <a href="{% url 'posts' %}">
        Post List
    </a>
    <h1>Create Blog post</h1>
    <form method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Save</button>
    </form>
{% endblock %}

  • {% csrf_token %}: CSRF 공격(Cross-site Request Forgery)을 방지하기 위한 코드를 입니다.
  • {{ form.as_p }}: 뷰(View)로부터 전달받을 파라메터 form으로부터 단락(as_p: Paragraph - <p> 태그) 형식으로 표시합니다. 이외에도 테이블(as_table - <table> 태그) 형식, 리스트(as_ul - <ul> 태그) 형식으로 표시할 수 있습니다. 이 기능을 통해 우리가 위에서 만든 form 클래스(class)에서 지정한 fields들이 표시됩니다.

URL 생성

다음으로, 새로운 URL을 생성하기 위해 blog/urls.py를 열고 아래와 같이 수정합니다.

from django.urls import path
from . import views

urlpatterns = [
    path('', views.posts, name='posts'),
    path('post/<int:id>/', views.post_detail, name='post_detail'),
    path('post/create/', views.post_create, name='post_create'), # <<<<<<<<<<< here
]

이 부분은 이전 블로그에서 설명하였기 때문에 설명을 생략하겠습니다. 이 부분에 대해서 이해가 잘 가시지 않는 분은 이전 블로그를 참고하시기 바랍니다.

뷰(View) 생성

마지막으로 데이터 처리를 위해 뷰(View)를 생성합니다. blog/views.py를 열고 아래와 같이 수정합니다.

from django.shortcuts import render, get_object_or_404, redirect
...
from django.utils import timezone
from .forms import PostCreateForm

...

def post_create(request):
    if request.method == "POST":
        form = PostCreateForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.published_at = timezone.now()
            post.save()
            return redirect('post_detail', id=post.id)
    else:
        form = PostCreateForm()
    return render(request, 'blog/post_create.html', {'form': form})
  • redirect: 데이터를 성공적으로 저장한 후 페이지를 다른 페이지로 리다이렉트(Redirect)시키기 위한 기능을 불러옵니다.
  • from django.utils import timezone: 블로그 데이터에 publised_at에 현재 날짜를 넣기 위해 기능을 불러옵니다.
  • if request.method == "POST": ... else: 우리가 선언한 함수에는 기본적으로 request 파라메터가 설정되어 있습니다. 이 request 파라메터의 method를 확인하여 GET/POST를 구별합니다. POST인 경우는 폼(Form)을 작성하여 데이터를 저장하는 경우입니다.
  • form = PostCreateForm(request.POST): 우리가 폼(Form)을 통해 전송한 POST 데이터는 request.POST에 담겨있습니다. 이 데이터를 가지고 우리가 생성한 PostCreateForm 폼 클래스(Form class)를 통해 폼 객체(Form object)를 생성합니다.
  • if form.is_valid(): 장고(django)가 기본적으로 제공하는 유효성 체크(Validation) 기능을 사용하여 POST로 보내온 데이터를 확인합니다. 우리는 블로그 Post 모델(Model)을 생성할 때, published_at에만 blank = True을 사용하였습니다. 따라서 이 필드 이외에 모든 필드는 필수(required) 필드가 적용됩니다.
  • post = form.save(commit=False): 폼 객체(Form object)를 통해 데이터를 저장(form.save)합니다. 하지만 commit=False 옵션을 통해 데이터베이스에 반영하지 않도록 설정합니다.
  • post.author = request.user: 위에서 바로 저장하지 않은 이유는 추가적인 데이터를 함께 저장하기 위해서 입니다. 저장할 데이터의 작성자(author)를 현재 request를 보낸 사용자로 넣습니다. 우리는 관리자 화면을 통해 이미 로그인한 상태임으로 request.user에는 관리자 화면에 로그인한 사용자 정보가 담겨져있습니다.
  • post.published_at = timezone.now(): 추가적으로 공개일(published_at)도 함께 넣어줌으로써 데이터가 화면에 바로 표시될 수 있도록 설정합니다.
  • post.save(): 최종적으로 데이터를 데이터베이스에 저장합니다.
  • return redirect('post_detail', id=post.id): 그리고 우리가 만든 데이터가 잘 저장되었는지 확인하기 위해 redirect 함수를 통해 post_detail 페이지로 리다이렉트(redirect) 시킵니다.
  • if request.method == "POST": ... else: 만약 보내온 요청(request)가 POST가 아닌 경우
  • form = PostCreateForm(): 우리가 만든 폼(Form)을 가져와 return render(request, 'blog/post_create.html', {'form': form}) 화면에 표시합니다.

링크 생성

위에서 만든 페이지로 활용하기 위해 메인 페이지인 blog/posts.html 파일을 열고 아래와 같이 수정합니다.


{% extends 'blog/layout.html' %}

{% block content %}
  <a href="{% url 'post_create' %}">Create Blog Post</a>
  {% for post in posts %}
    ...
  {% endfor %}
{% endblock %}

확인

지금까지 작업한 내용을 확인하기 위해 http://127.0.0.1로 접속합니다.

장고(django)의 폼(Form) - 메인 페이지

그러면 위와 같이 우리가 새로 추가한 Create Blog Post 링크가 보이는 메인 페이지를 확인할 수 있습니다. Create Blog Post 링크를 눌러 블로그 작성 페이지로 이동합니다.

장고(django)의 폼(Form) - 블로그 작성 페이지

그러면 위와 같이 폼(Form) 작성 페이지를 확인할 수 있습니다. 여러분이 저장하길 원하는 데이터를 넣고 Save 버튼을 눌러 데이터를 저장합니다.

장고(django)의 폼(Form) - 상세 페이지

데이터 저장 완료후 우리는 상세 페이지로 리다이렉트(Redirect)되도록 작업하였기 때문에, 위와 같이 저장된 데이터의 상세 페이지로 이동하게 됩니다.

마지막으로 상단에 Post List 링크를 눌러 메인 페이지로 이동해 봅니다.

장고(django)의 폼(Form) - 데이터가 추가된 메인 페이지

메인 페이지에서 위와 같이 우리가 추가한 데이터가 표시되는 걸 확인할 수 있습니다.

완료

이것으로 장고(django)의 폼(Form)을 사용하는 방법에 대해서 알아보았습니다. 또한 뷰(View)에서 사용자의 요청(Request)을 GET과 POST로 구분하여 다르게 처리하는 방법에 대해서도 알아 보았습니다. 이것으로 우리는 사용자가 보내온 데이터를 저장하거나 수정할 수 있게 되었습니다.

Buy me a coffeeBuy me a coffee
Posts