FormViewとは
具体的には以下のような画面
https://sample-apps.box16.site/morpholy/
(上記の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
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クラスを使う
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クラスを以下のように埋め込める
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Send message">
</form>
result.htmlはresult_viewに紐づく
{% 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で行う
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のテンプレートはめっちゃ簡単にかける