개요
지금까지는 장고(django)가 기본적으로 제공하는 관리자 페이지(Administrator)를 사용하여 데이터를 추가하거나 수정하였습니다. 이번 블로그에서는 장고(django)의 폼(Form)을 이용하여 데이터를 추가하거나 수정하는 방법에 대해서 알아보도록 하겠습니다.
이 블로그는 시리즈로 작성되어 있으며, 아래에 링크를 통해 시리즈의 다른 글을 확인할 수 있습니다.
이 블로그는 시리즈로 작성되어 있으며, 아래에 링크를 통해 시리즈의 다른 글을 확인할 수 있습니다.
- 장고(django) 설치하기
- 장고(django) 프로젝트 시작하기
- 장고(django) 모델(models) 사용해보기
- 장고(django)의 관리자 페이지
- 장고(django)의 라우팅(Routing)
- 장고(django)의 ORM
- 장고(django)의 뷰(View)
- 장고(django)의 폼(Form)
- 장고(django) 프로젝트를 헤로쿠(heroku)에 업로드하기
또한 이 블로그 시리즈에서 다룬 소스는 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이라는 이름으로 클래스를 생성하고 forms.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
]
이 부분은 이전 블로그에서 설명하였기 때문에 설명을 생략하겠습니다. 이 부분에 대해서 이해가 잘 가시지 않는 분은 이전 블로그를 참고하시기 바랍니다.
- 이전 블로그: 장고(django)의 뷰(View)
뷰(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
: 블로그 데이터에published_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
로 접속합니다.

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

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

데이터 저장 완료후 우리는 상세 페이지로 리다이렉트(Redirect)되도록 작업하였기 때문에, 위와 같이 저장된 데이터의 상세 페이지로 이동하게 됩니다.
마지막으로 상단에 Post List
링크를 눌러 메인 페이지로 이동해 봅니다.

메인 페이지에서 위와 같이 우리가 추가한 데이터가 표시되는 걸 확인할 수 있습니다.
완료
이것으로 장고(django)의 폼(Form)을 사용하는 방법에 대해서 알아보았습니다. 또한 뷰(View)에서 사용자의 요청(Request)을 GET과 POST로 구분하여 다르게 처리하는 방법에 대해서도 알아 보았습니다. 이것으로 우리는 사용자가 보내온 데이터를 저장하거나 수정할 수 있게 되었습니다.
제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!
앱 홍보
Deku
가 개발한 앱을 한번 사용해보세요.Deku
가 개발한 앱은 Flutter로 개발되었습니다.관심있으신 분들은 앱을 다운로드하여 사용해 주시면 정말 감사하겠습니다.