ユーニックス総合研究所

  • home
  • archives
  • python-django-linebbs-create-form

Django入門: フォームを作る ~ 簡単な一行掲示板アプリを作る その12【Windows10】

  • 作成日: 2020-10-24
  • 更新日: 2023-12-26
  • カテゴリ: Django

はじめに

この記事は「Djangoで一行掲示板を作ろう」という趣旨のシリーズの記事です。

前回までにDjangoのプロジェクトとアプリを作成し、ルート情報とビューを接続し、テンプレートを描画して、モデルを作りマイグレーションを行い、ビューでオブジェクトを取得し、管理サイトでオブジェクトを追加してテンプレートで表示する処理を書きました。

今回からDjangoのフォームについてやっていきたいと思います。

前提として開発環境のOSはWindows10, シェルはコマンドプロンプトです。
仮想環境を使っていますが、仮想環境については第一回の記事をご覧ください。
初期作業ディレクトリはプロジェクト内のmanage.pyのあるディレクトリです。

フォーム

前回までに掲示板の投稿内容をリストで表示するというコードを書いてきました。
今回から数回に渡ってこのリストの上部にフォームを作りたいと思います。
掲示板の利用者はこのフォームから掲示板にデータを投稿(POST)します。

HTMLで投稿用フォームを作るにはformタグをはじめとしたinputタグなどを使ってフォームを形作る必要があります。
Djangoには、このフォームの一部、inputタグを抽象化する仕組みが備わっています。

また、フォームとモデルは互いに連携することが可能で、フォームの制作の一部をモデルに任せることもできます。
これによってフォームを作る場合の開発者の手間が減り、開発効率を上げることが可能です。

Djangoのフォームはクラスで作ります。
そしてこのクラスはforms.pyというモジュール内に置かれるのが一般的です。
forms.pyはアプリのディレクトリ以下に配置します。

forms.pyの作成

forms.pyを作成します。
manage.pyのあるディレクトリからbbs\forms.pyを新規作成して↓のように編集します。

from django import forms  
from bbs.models import Post  


class PostForm(forms.ModelForm):  
    class Meta:  
        model = Post  
        fields = ('content', )  

まず↓の部分ですが、

from django import forms  
from bbs.models import Post  

Djangoのフォームを利用するためにformsモジュールをインポートしています。
Postは掲示板のモデルです。

class PostForm(forms.ModelForm):  
    class Meta:  
        model = Post  
        fields = ('name', 'content')  

↑の部分では実際にフォームPostFormを定義しています。
formsにはいろいろなクラスがあるのですが、今回はこのforms.ModelFormを使ってフォームを作ります。
ModelFormはモデルをフォームとして流用するクラスです。
内部のMetaクラスのmodel属性に↑のようにモデルを指定することで機能します。
また、モデルから流用するフィールドをfieldsに指定します。

このPostFormはビュー、そしてテンプレートから利用されます。

ビューのリファクタリング

先ほど作成したPostFormはオブジェクトにすることができます。
このオブジェクトをビューからコンテキストに保存し、テンプレートに渡して利用します。

フォームを利用するにあたってすでに書いてあるビューのコードをリファクタリングします。
bbs\views.pyを開いて↓のように編集します。

from django.shortcuts import render  
from django.http import HttpResponse  
from bbs.models import Post  


def home_view(request):  
    """  
    パス bbs/ のテンプレートを出力するビュー  
    """  

    # request.methodによって処理を分岐  
    if request.method == 'GET':  
        return home_view_get(request)  
    elif request.method == 'POST':  
        return home_view_post(request)  
    else:  
        return HttpResponse('invalid method', status=400)  


def home_view_get(request):  
    """  
    パス bbs/ の GET  
    """  
    context = {}  # コンテキストを作成  

    context['title'] = '一行掲示板'  # ページのタイトル  
    context['posts'] = Post.objects.all()  # Postのリストを取得  

    # renderにコンテキストを渡しテンプレートを描画  
    return render(request, 'bbs/home.html', context)  


def home_view_post(request):  
    """  
    パス bbs/ の POST  
    """  
    return HttpResponse('TODO')  # 後で実装  

↑の例ではhome_viewがパスbbs/の入口になっています。
そしてrequest.methodの値によってさらに呼び出す関数を分岐しています。

request.methodにはブラウザからWebサーバーに送信されたリクエストのメソッド名が入っています。
Webページの取得には通常、GETメソッドを使います。これは「Webページのデータをください」というメソッドです。
いっぽう、掲示板への投稿などではPOSTメソッドが使われます。これは「Webページからデータを投稿させてください」というメソッドです。

フォームを使った掲示板では主にこの2つのメソッドが使われます。
そのため、↑でもそれぞれのメソッドによって処理を分岐しています。

home_view_get()GETメソッドの場合に呼び出される関数で、中身は以前まで使っていたコードと変わりません。
そしてhome_view_post()POSTメソッドの場合に呼び出される関数で、中身は仮実装になっています。

home_view()では対応していないメソッドが使われた場合は、↓のようにHttpResponseを返すようになっています。

return HttpResponse('invalid method', status=400)  

HttpResponseの第1引数にはレスポンスの内容、そしてstatus引数にはHTTPステータスコードを渡します。
HTTPステータスコードと言うのは、Webサーバーがブラウザに返すリクエストの結果です。
ブラウザからWebサーバーへのリクエストが成功したか、あるいはエラーが発生したか知りたい場合はこのステータスコードを確認します。
今回の場合、対応していないメソッドが使われたのでHTTPステータスコードは400にしています。
HTTPステータスコードでは400は↓のような定義になっています。

400 Bad Request
リクエストが不正である。定義されていないメソッドを使うなど、クライアントのリクエストがおかしい場合に返される。

おわりに

今回はDjangoのフォームの作成と、フォームの利用のためのビューのリファクタリングを行いました。
次回から実際にフォームを使っていきたいと思います。

🦝 < フォームは続くよどこまでも