January 23, 2021
←前回:Day 17 FromとHTMLのレンダリングの関係を理解する
「Djangoを学びたい」とのことでありましたら[Day 1]Djangoの開発環境から読むことをおすすめします。
#はじめに
前回まで、トピックの作成処理はthread/views.pyにtpic_create関数で処理を書きました。
今回はフォームで受けたデータを保存する処理をFormViewをCreateViewを使って書いていきましょう。
#FormViewを使う
FormViewはTemplateViewを継承したクラスで受け取ったデータの精査の成功と失敗での別々の処理をします。
まずはtopic_create関数をFormViewを使って書き直してみましょう。
from django.shortcuts import render, redirect
from django.views.generic import CreateView, FormView
from django.urls import reverse_lazy
from . forms import TopicCreateForm
from . models import Topic
class TopicFormView(FormView):
template_name = 'thread/create_topic.html'
form_class = TopicCreateForm
success_url = reverse_lazy('base:top')
def form_valid(self, form):
form.save()
return super().form_valid(form)
def topic_create(request):
template_name = 'thread/create_topic.html'
ctx = {}
if request.method == 'GET':
ctx['form'] = TopicCreateForm()
return render(request, template_name, ctx)
if request.method == 'POST':
topic_form = TopicCreateForm(request.POST)
if topic_form.is_valid():
topic_form.save()
return redirect(reverse_lazy('base:top'))
else:
ctx['form'] = topic_form
return render(request, template_name, ctx)
thread/urls.pyも書き直します。
urlpatterns = [
path('create_topic/', views.TopicFormView.as_view(), name='create_topic'),
# path('create_topic/', views.topic_create, name='create_topic'),
]
これでlocalhost:8080/thread/create_topic/にアクセスしてみましょう。
フォームに入力して「作成」ボタンを押すと作成が成功すればTOP画面に遷移するはずです。
現段階では作成したトピックが見れないので管理画面で確認しましょう。
管理画面で確認
ここで行っている処理自体は書き直す前の関数と同じ処理です。
FormViewはTemplateViewを継承しているのでGETで受けた場合にはtemplate_nameで指定されたテンプレートを表示します。
その際にform_classで指定されたフォームを’form’という名前でコンテキストとして渡します。
POSTされた際にはform_valid関数が呼ばれデータの精査が行われ、成功すればsuccess_urlに遷移します。
もし失敗した場合はエラー情報をフォームに格納して再度template_nameのテンプレートを表示します。
今回はform_valid関数をオーバーライドして保存処理を行っています。
#CreateViewを使ってみる
さて、thread/views.pyの内容をクラスベースビューの1つであるCreateViewを使って書き直してみましょう。
CreateViewはFormViewを継承しているのでもっとシンプルに書くことができますよ。
from django.shortcuts import render, redirect
from django.views.generic import CreateView
from django.urls import reverse_lazy
from . forms import TopicCreateForm
from . models import Topic
class TopicCreateView(CreateView):
template_name = 'thread/create_topic.html'
form_class = TopicCreateForm
model = Topic
success_url = reverse_lazy('base:top')
当然urls.pyも変更します。
from django.urls import path
from . import views
app_name = 'thread'
urlpatterns = [
path('create_topic/', views.TopicCreateView.as_view(), name='create_topic'),
# path('create_topic/', views.topic_create, name='create_topic'),
]
CreateViewはGETメソッドで受けた場合にtemplate_nameで指定されたテンプレートを表示します。
その際にform_classで指定されたフォームを’form’という名前でコンテキストとして渡します。
POSTでデータを受けた際にはformのデータを精査して正しいデータであれば保存処理を行い、success_urlにリダイレクトします。
もし正しいデータでなければ、エラー内容を含んだformを渡してtemplate_nameで指定されたテンプレートを表示する。
という処理を行います。この処理は最初に出てきたcreate_topic関数と同じ処理を行っていますよね。
#終わりに
現在かなり混乱しています。
最近かなりインプットしっぱなしなので、ちょっとどこかのタイミングで整理しないといけないですね。
それではまたまた
←前回:Day 17 FromとHTMLのレンダリングの関係を理解する
→次回:Day 19 確認画面付きのトピック作成画面を作る