LoginSignup
6
8

More than 3 years have passed since last update.

[Django][Python]FormViewの使い方

Posted at

FormViewとは

具体的には以下のような画面
https://sample-apps.box16.site/morpholy/
image.png

(上記のWebアプリは自分が作ったもので、入力した文字列を形態素解析するという簡単なもの
Github : https://github.com/box16/morpholy)

こういったForm(何かしらの情報を入力できるHTML要素)をまとめて1画面にできるDjangoの汎用ViewがFormView
詳細は以下から確認できます
https://docs.djangoproject.com/en/3.1/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView

FormViewの使い方

1. forms.pyを作成する

まず、どんなFormを用意するのかを記述するためにforms.pyを作成します
配置するのはアプリディレクトリ配下

.
├── __init__.py
├── admin.py
├── apps.py
├── forms.py ← ここ!!
├── migrations
│── models.py
├── templates
│── tests.py
├── urls.py
└── views.py
forms.py
from django import forms


class MorpholyForm(forms.Form):
    text = forms.CharField(widget=forms.Textarea,
                           label="解析対象")

    select_part = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
        choices=[("名詞", "名詞"), 
                 ("動詞", "動詞"), 
                 ("形容詞", "形容詞"), ],
        label="出力項目",
        error_messages={'required': '出力項目を選んでください'})

forms.Formを継承したクラスを作成します(今回の例ではMorpholyForm)
クラス内に、formを定義していきます

今回の例では、文字列を入力させるためのforms.CharField,形態素解析対象を選択するforms.MultipleChoiceField
を用意してます

2. views.pyでFormクラスを使う

まず、以下の画面をindexとして作成
image.png

これの結果出力をresultとして作成
image.png

views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.views.generic.edit import FormView
from .forms import MorpholyForm
from .extensions import NLP

nlp = NLP()

# postされた情報を一時的に格納するためのディクショナリ
posted_data = {"text": "",
               "select_part": []}


class IndexView(FormView):
    template_name = 'morpholy/index.html'
    form_class = MorpholyForm # forms.pyで作ったFormクラスをここで使う
    success_url = 'result' # formに入力された値が正しければこのURLに飛ぶ

    def form_valid(self, form):
        posted_data["text"] = form.data.get("text") # Formに入力された値を取得(getメソッドはリストの場合最後の値を取得)
        posted_data["select_part"] = form.data.getlist("select_part")# getlistメソッドはリストすべてを取得
        return super().form_valid(form)


def result_view(request):
    result = nlp.extract_parts(
        text=posted_data["text"],
        select_part=posted_data["select_part"])
    return render(request, 'morpholy/result.html', {"part_result": result})

3. viewと紐づけるTemplateの作成

index.htmlはIndexViewと紐づく
forms.pyで作成したFormクラスを以下のように埋め込める

index.html
<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Send message">
</form>

result.htmlはresult_viewに紐づく

result.html
{% if part_result %}
    {% for part,result_list in part_result.items %}
        <h2>{{part}}</h2>
            <p>
                {% for result in result_list %}
                    {{result}} , 
                {% endfor %}
            </p>
    {% endfor %}
{% else %}
    <p>解析に失敗しました</p>
{% endif %}

<p>
    <a href="{% url 'morpholy:index' %}">入力画面に戻る</a>
</p>

4. urls.pyでルーティング

URLとViewの紐づけをurls.pyで行う

urls.py

from django.urls import path

from . import views

app_name = "morpholy"
urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('result', views.result_view, name='result'),
]

まとめ

  • FormViewはこんな感じのViewが作れる汎用View

    https://sample-apps.box16.site/morpholy/

  • Formクラスを継承したサブクラスを用意する

  • formに入力された値は、get,getlistで取得する

  • FormViewのテンプレートはめっちゃ簡単にかける

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8