【Django】クラスベースビューの補足:UpdateViewの見えない処理と仕組みについて

概要

以下のUpdateViewを使用したタスク編集処理について、見えない親クラスの処理をざっくりと見える化してどのような流れで編集画面を表示した後に更新しているのかをまとめた。

 

あわせて読みたい

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

【Django】クラスベースビュー(class-based view):UpdateViewを使用したタスク編集機能の実装:アイキャッチ画像

 

UpdateView

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

UpdateViewのタスク編集機能実装例

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

todoapps.views.py


class TodoEditView(LoginRequiredMixin, UpdateView):
    """タスク編集画面"""

    # DB更新モデル
    model = models.Todo
    # テンプレート
    template_name = "todo/edit.html"
    # タスク編集フォーム
    form_class = forms.TodoEditForm

    def get_context_data(self, **kwargs):
        """コンテキストをオーバーライドする"""
        context = super().get_context_data(**kwargs)
        # カテゴリ一覧の設定
        context["categories"] = models.TodoCategory.objects.all()
        return context

    def get_success_url(self):
        """更新完了後のリダイレクトURLを返却する"""
        return reverse_lazy("detail", kwargs={"pk": self.object.pk})

 

GETリクエストの処理概要

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

【Django】クラスベースビューの補足:UpdateViewの見えない処理と仕組みについて_GETリクエスト
▲GET処理の流れ

解説

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

全体の流れ

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

 

dispatch()メソッド

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

 

データ検索処理

クエリパラメータをもとに、model名に設定したテーブルオブジェクトからレコードデータを取得する。

 

コンテキスト設定

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

 

レスポンス返却

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

 

POSTリクエストの処理概要

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

【Django】クラスベースビューの補足:UpdateViewの見えない処理と仕組みについて_POSTリクエスト
▲POST処理の流れ

 

解説

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

全体の流れ

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

 

dispatch()メソッド

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

 

画面入力値取得

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

 

入力チェック

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

 

エラー処理

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

 

コンテキスト設定

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

 

レスポンス返却

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

 

メイン処理

DB検索した値と画面入力値をもとにDB更新を行う。

 

リダイレクト処理

今回リダイレクト先は詳細画面としている。
詳細画面を表示する際にはクエリパラメータを付与する必要があり、動的にURLを作成することになる。
動的にURLを作成する場合、success_urlフィールドにURLを設定するのではなく、get_success_urlをオーバーライドする必要がある。

動的にURLを作成する場合、以下のように記述する。

def get_success_url(self):
    """更新完了後のリダイレクトURLを返却する"""
    return reverse_lazy("detail", kwargs={"pk": self.object.pk})

 

スポンサーリンク