ジャンゴ(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と言う名前でクラス(Class)を生成して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