【Django】クラスベースビューの補足:CreateViewの見えない処理と仕組みについて(タスク登録機能)

概要

以下のCreateViewを使用したタスク登録処理について、見えない親クラスの処理をざっくりと見える化して全体のどこの処理をオーバーライドしているのかをまとめた。

あわせて読みたい

概要 クラスベースビュー(class-based view)でタスク登録機能を作成したのでまとめた。 タスク登録機能は、Djangoがもともと用意しているCreateViewクラスを継承して作成する。 CreateViewをどのよ[…]

 

CreateView

CreateViewの見えない処理をざっくりと見える化して、オーバーライドして実装する箇所は全体のどこにあたるのかを説明する。

CreateViewのタスク登録機能実装例

CreateViewを使用したタスク登録機能は例えば以下のように実装する。

todoapps.views.py


class TodoCreateView(LoginRequiredMixin, CreateView):	
    """タスク登録画面"""	
	
    # DB登録モデル	
    model = models.Todo	
    # テンプレート	
    template_name = "todo/create.html"	
    # タスク登録フォーム	
    form_class = forms.TodoForm	
    # 登録成功後リダイレクトURL	
    success_url = reverse_lazy("top")	
	
    def get_context_data(self, **kwargs):	
        """コンテキストをオーバーライドする"""	
        # 既存のコンテキスト取得	
        context = super().get_context_data(**kwargs)	
        # カテゴリ一覧の追加	
        context["categories"] = models.TodoCategory.objects.all()	
        return context	
	
    def form_valid(self, form):	
        """フォームバリデーション後の処理"""	
        # ステータスをデフォルトで0(未完了)に設定	
        form.instance.status = consts.TASK_STATUS_IMCOMPLETE	
        # モデル情報にuserを追加	
        form.instance.user = self.request.user	
        # DB登録処理呼び出し	
        return super().form_valid(form)	

 

GETリクエストの処理概要

細かい内容は割愛して、大きな処理の流れは以下となる。

▲GET処理の流れ

 

解説

それぞれの処理について解説する。

全体の流れ

画面に渡すフォームを取得する。
フォームは画面とサーバー間でデータの受け渡しをするための「箱」というイメージ。
フォームの箱をコンテキストに設定して、画面テンプレートとコンテキストを組み合わせたHTMLをレスポンスとして返却する。

 

dispatch()メソッド

ブラウザからのリクエストをもとに、get()メソッドまたはpost()メソッドの呼び出しを制御する。
今回はget()メソッドを呼び出す。

 

コンテキスト設定

get_formを呼び出し、空のTodoFormインスタンスを生成する。
今回はCreateViewをオーバーライドしたクラスでフォーム名(form_class)にTodoFormを設定しているため。
生成した空のフォームインスタンスをコンテキストに設定している。
また、画面側でカテゴリ一覧のセレクトボックスを表示するため、カテゴリテーブルから全検索したデータを取得してコンテキストに渡している。

 

レスポンス返却

コンテキストと”todo/create.html”を組み合わせた画面を返却する。
今回はtemplate_nameに”todo/create.html”を設定しているため、”todo/create.html”とコンテキストを組み合わせた画面をレスポンスしている。

 

POSTリクエストの処理概要

細かい内容は割愛して、大きな処理の流れは以下となる。

▲POST処理の流れ

 

解説

それぞれの処理について解説する。

全体の流れ

画面入力値を保持したフォームインスタンスを取得する。
フォームインスタンス内で入力チェックを行う。
入力チェックエラーが有る場合、エラー情報を保持したフォームインスタンスをコンテキストに設定して画面に返却する。
入力チェックエラーが無い場合、フォームの画面入力値をDBに登録する。

 

dispatch()メソッド

ブラウザからのリクエストをもとに、get()メソッドまたはpost()メソッドの呼び出しを制御する。
今回はpost()メソッドを呼び出す。

 

画面入力値取得

画面入力値を保持したTodoFormインスタンスを取得する。

 

入力チェック

TodoFormインスタンス内で入力チェックを行う。
エラーがある場合、インスタンス内にてエラー情報を保持する。

 

エラー処理

入力チェックエラーとなった場合に呼ばれる。
コンテキストを設定する処理を呼び出し、レスポンスを返却する処理を呼び出す。

 

コンテキスト設定

エラー情報を保持したフォームインスタンスをコンテキストに設定する。
また、カテゴリ一覧をDB検索してコンテキストに設定する。

 

レスポンス返却

コンテキストと”todo/create.html”を組み合わせた画面を返却する。

メイン処理

form_valid()メソッドをオーバーライドすることで、メインとなる処理を定義できる。
今回は画面入力値の値だけだとTodoテーブルに登録できないため、以下のように足りないカラム情報を追加している。

# ステータスをデフォルトで0(未完了)に設定
form.instance.status = consts.TASK_STATUS_IMCOMPLETE
# モデル情報にuserを追加
form.instance.user = self.request.user

 

DB登録呼び出しで親クラスのform_valid()を呼び出しているが、親クラスのform_valid()は以下の実装になる。

def form_valid(self, form):
    """If the form is valid, save the associated model."""
    self.object = form.save()
    return super().form_valid(form)

上記のsaveメソッドでDB登録する。
modelに設定したクラスに紐づくテーブルに登録される。
ちなみにさらに親クラスのform_validを読んでいるが、この処理はリダイレクトを呼んでいるだけ。

 

リダイレクト処理

リダイレクトしたいURLを指定することで、登録完了後にリダイレクトされる。
success_urlに設定したURLへリダイレクトする。

 

スポンサーリンク