This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 3 years have passed since last update.

[Day 18]FormViewとCreateViewを使う

Last updated at Posted at 2021-01-23

January 23, 2021
←前回:Day 17 FromとHTMLのレンダリングの関係を理解する

「Djangoを学びたい」とのことでありましたら[Day 1]Djangoの開発環境から読むことをおすすめします。

はじめに

前回まで、トピックの作成処理はthread/views.pyにtpic_create関数で処理を書きました。
今回はフォームで受けたデータを保存する処理をFormViewをCreateViewを使って書いていきましょう。

FormViewを使う

FormViewはTemplateViewを継承したクラスで受け取ったデータの精査の成功と失敗での別々の処理をします。
まずはtopic_create関数をFormViewを使って書き直してみましょう。

thread/views.py

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も書き直します。

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画面に遷移するはずです。
現段階では作成したトピックが見れないので管理画面で確認しましょう。
image.png
管理画面で確認
image.png
ここで行っている処理自体は書き直す前の関数と同じ処理です。
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

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も変更します。

thread/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 確認画面付きのトピック作成画面を作る

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