1-17. FormViewとCreateViewを使う

今回のテーマは「FormViewとCreateViewを使う」です。前回まで、トピックの作成処理はthread/views.pyにtpic_create関数で処理を書きました。今回はフォームで受けたデータを保存する処理をFormViewをCreateViewを使って書いていきましょう。 ※本ページはFormとHTMLレンダリングの関係を理解するまで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。


FormViewを使う

FormViewはTemplateViewを継承したクラスで受け取ったデータの精査の成功と失敗での別々の処理をします。まずはtopic_create関数と同じ役割を持つクラスをFormViewを使って追加してみましょう。

thread/views.py

#importは適宜追加
from django.views.generic import DetailView, TemplateView, FormView

#...他のクラスや関数は省略

class TopicFormView(FormView):
    """トピック投稿用関数

    FormViewの練習用クラスとして作成

    """
    template_name = 'thread/create_topic2.html'
    form_class = TopicCreateForm
    success_url = reverse_lazy('base:top')

    def form_valid(self, form):
        form.save()
        return super().form_valid(form)

今作作成したthread/urls.pyも書き直します。

thread/urls.py

#...省略

urlpatterns = [
    #...省略

    # シンプルなトピック投稿画面
    #path('/create_topic/', views.simple_topic_create, name='create_topic'),
    #path('/create_topic/', views.topic_create, name='create_topic'),
    path('/create_topic/', views.TopicFormView.as_view(), 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を継承しているのでもっとシンプルに書くことができますよ。

thread/views.py

#importは適宜追加
from django.views.generic import DetailView, TemplateView, FormView, CreateView

#...他のクラスや関数は省略

class TopicCreateView(CreateView):
    """トピック投稿用関数

    CreateViewの練習用クラスとして作成

    """
    template_name = 'thread/create_topic2.html'
    form_class = TopicCreateForm
    model = Topic
    success_url = reverse_lazy('base:top')

当然urls.pyも変更します。

thread/urls.py

#...省略

urlpatterns = [
    #...省略

    # シンプルなトピック投稿画面
    #path('/create_topic/', views.simple_topic_create, name='create_topic'),
    #path('/create_topic/', views.topic_create, name='create_topic'),
    #path('/create_topic/', views.TopicFormView.as_view(), name='create_topic'),
    path('/create_topic/', views.TopicCreateView.as_view(), name='create_topic'),
]

CreateViewはGETメソッドで受けた場合にtemplate_nameで指定されたテンプレートを表示します。その際にform_classで指定されたフォームを’form’という名前でコンテキストとして渡します。POSTでデータを受けた際にはformのデータを精査して正しいデータであれば保存処理を行い、success_urlにリダイレクトします。もし正しいデータでなければ、エラー内容を含んだformを渡してtemplate_nameで指定されたテンプレートを表示する。という処理を行います。この処理は最初に出てきたcreate_topic関数と同じ処理を行っていますよね。

最後に

ちょっと混乱してしまったでしょうか?Djangoは関数でガリガリ自分で書くことも出来ますが、目的に応じたプリセットクラスを使うことでよりスマートに書くことも出来ます。次回は確認画面がある登録画面を作成していきます。

Sponsored Link


コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です