How-To's Web Development

Django ビュー入門

Read this post in other languages:

ビューは Django のアーキテクチャパターンの中心となるものであるため、このフレームワークを使用する開発者はその扱い方をしっかり理解しておくことが不可欠です。 Django を使用したウェブアプリの開発が初めての方や、ビューのおさらいが必要な方は、ぜひこの記事をお読みください。

ビューをよく理解することで、Django プロジェクトをより迅速に進めることができます。 扱い対象が API バックエンドであれ、ウェブ UI のフローであれ、ビューの使用方法を知っておくことは非常に重要です。

この記事では Django ビューの概要と種類、その使用に関するベストプラクティスを説明し、ユースケースの例を紹介します。

Django ビューとは?

ビューは、Django の MTV(モデル・テンプレート・ビュー)アーキテクチャパターンの中心となるコンポーネントです。 ビューは基本的にはモデルテンプレートの仲介者の役割を果たすもので、ユーザーのリクエストを処理して応答を返します。

MVC(モデル・ビュー・コントローラー)パターンのビューを見たことのある方はいるかもしれませんが、 それは Django のビューとは若干異なるため、まったく同じように解釈することはできません。 Django ビューは実質的には MVC のコントローラーであり、Django テンプレートは概して MVC のビューに相当するものです。 このため、たとえ MVC の文脈でビューを理解している方でも、Django ビューの意味合いを理解することは非常に重要です。

ビューは Django のユーザーインターフェースの一部であり、Django を使用したアプリとサイトに対するウェブリクエストのロジックとデータ処理を担い、 テンプレートをユーザーがウェブページを閲覧する際に表示される内容にレンダリングします。 関数ベースまたはクラスベースビューは、ユーザーのリクエストを受け取ると、そのモデルからデータを取得してビジネスロジックやデータ処理を適用し、その上で HTTP 応答を準備してテンプレートに返します。

この応答とは、ウェブブラウザーが表示できるあらゆるデータです。通常は HTML ウェブページですが、 Django ビューは画像、XML ドキュメント、リダイレクト、エラーページなども返すことができます。

テンプレートのレンダリングとデータの受け渡し

Django には、ビュー内からのテンプレートのレンダリングを単純化できる render() ショートカットが備わっています。 render() を使用すると、手動でテンプレートを読み込んで応答を作成するという定型的なロジックを書かずに済みます。

PyCharm のビューで django.shortcutsrender() 関数の入力を開始すると、スマートコード補完によってそれが自動的に提案されます。 また、PyCharm はテンプレート名を認識してテンプレートのパスを自動補完するため、タイポやエラーの回避に役立ちます。

ユーザーはリクエスト、テンプレート名、テンプレートのデータとなるコンテキスト辞書を指定します。 必要なデータが取得されると、ビューはそれをテンプレートに渡し、テンプレートがレンダリングされてユーザーに表示されます。

from django.shortcuts import render

def my_view(request):
    # Some business logic to obtain data
    data_to_pass = {'variable1': 'value1', 'variable2': 'value2'}

    # Pass the data to the template
    return render(request, 'my_template.html', context=data_to_pass)

この例では、data_to_pass がテンプレートに送信されるデータを含む辞書として定義されています。 その後に render 関数が使用され、指定したコンテキストデータを使用してテンプレート(my_template.html)がレンダリングされています。

これで、テンプレート(my_template.html)内でデータにアクセスし、表示できるようになりました。


    

{{ variable1 }}








    
{{ variable2 }}

テンプレートでは、二重波括弧({{ }})を使用してテンプレート変数を示します。 テンプレート変数は、ビューによって渡されたコンテキストデータの値に置換されます。

PyCharm では、Django テンプレートのタグ、変数、およびループに対応した補完と構文ハイライトが提供されます。 エディター内ではよくあるミスを検出するリントも提供されます。 そのため、ユーザーはテンプレート要素の手動入力やよくあるエラーのデバッグに時間をかけることなく、ビューの構築とロジックの処理に専念できます。

PyCharm における Django の補完

関数ベースビュー

Django ビューには、関数ベースビューとクラスベースビューの 2 種類があります。

関数ベースビューは単純な Python 関数を使用して構築されており、概して作成、読み出し、更新、削除(CRUD)の 4 つの基本カテゴリに分けられます。 これは、開発におけるあらゆるフレームワークの基本です。 このようなビューは HTTP リクエストを受け取り、HTTP 応答を返します。

from django.http import HttpResponse

def my_view(request):

    # View logic goes here
    context = {"message": "Hello world"}

    return HttpResponse(render(request, "mytemplate.html", context))

このスニペットはビューのロジックを担っており、データをレンダリングされるテンプレートに渡すためのコンテキスト辞書を準備し、最終的なテンプレートの HTML を応答オブジェクトとして返します。

関数ベースビューは単純明快です。 ロジックがクラス内の複数のメソッドにわたって分散されず、1 つの Python 関数内に書かれるため、処理を最小限に抑えたユースケースに最適です。

PyCharm では、ライブテンプレートを使用して def my_view(request) 構造を自動的に生成することができます。 ライブテンプレートは事前定義済みのコードスニペットですが、ボイラープレートコードに拡張することができます。 この機能を使用すると時間を節約でき、ビューの定義で一貫した構造を確保することができます。

ライブテンプレートは、⌘J を押し、Listview と入力して Tab キーを押すと呼び出せます。

さらに、PyCharm には Django プロジェクト内のすべてのビューのリストをアプリ別に表示できる Django Structure(Django 構造)ツールウィンドウがあります。 そのため、ビューの場所を素早く探し出し、複数のビュー間を移動し、各ビューが属するファイルを特定することができます。

クラスベースビュー

Django では何度も同じコードを書かなくても済むようにするため、クラスビューが導入されています。 これは関数ベースビューに取って代わるものではなく、複雑なロジックが必要な場合などで一定の用途とメリットがあります。

Django のクラスベースビューは、ウェブアプリケーションビューで一般的に必要とされるさまざまなパターンと機能を実装する再利用可能な親クラスを提供します。 このような親クラスのビューを使用すると、ボイラープレートコードを削減できます。

クラスベースビューには、以下のような汎用の親クラスが用意されています。

  • ListView
  • DetailView
  • CreateView
  • およびその他多数

以下は、単純な BookListView の実例を示す 2 つの類似するコードスニペットです。最初のスニペットではデフォルトのクラスベース手法による基本的な実装を示しており、2 つ目のスニペットでは追加パラメーターを指定してそのビューをカスタマイズできることを説明しています。

基本的な実装:

from django.views.generic import ListView
from .models import Book 

class BookListView(ListView):
    model = Book
    # The template_name is omitted because Django defaults to 'book_list.html' 
    # based on the convention of _list.html for ListView.

BookListView がレンダリングされると、Book レコードが自動的にクエリされ、book_list.html をレンダリングする際にそのレコードが books 変数の下で渡されます。 そのため、元になるロジックを書き直さなくても、オブジェクトをリストするビューを素早く作成できます。

カスタム実装:

from django.views.generic import ListView
from .models import Book 

class BookListView(ListView):

    model = Book
	# You can customize the view further by adding additional attributes or methods 
    def get_queryset(self):
	# Example of customizing the queryset to filter books
	return Book.objects.filter(is_available=True)

2 つ目のスニペットには、カスタムの get_queryset() メソッドが導入されており、ビューに表示されるレポートをより正確に絞り込めるようになっています。 これは、クラスベースビューをアプリケーションのニーズに合わせてデフォルトの機能を超えて拡張できることを示しています。

クラスベースビューは、以下のようなリクエストと応答のライフサイクルの重要な部分に関係するメソッドも定義しています。

  • get()GET リクエスト用のロジック。
  • post()POST リクエスト用のロジック。
  • dispatch()get() または post() のどちらのメソッドを呼び出すかを判定します。

この種のビューは構造化できると同時に必要に応じてカスタマイズできるため、複雑なユースケースに適しています。

PyCharm には ListViewDetailViewTemplateView といったクラスベースビューのライブテンプレートが備わっているため、view クラス全体を数秒で生成し、ボイラープレートメソッドと docstring を使用して完成させることができます。

PyCharm における Django のライブテンプレート

カスタムクラスベースビューの作成

Django の汎用ビューをサブクラス化してニーズに合わせてカスタマイズすることで、独自のビュークラスを作成することもできます。

以下のようなユースケースでは、独自のクラスを作るとよいでしょう。

  • 複雑な計算などのビジネスロジックを追加する。
  • 複数の汎用親クラスを組み合わせて機能を生成する。
  • 複数のリクエストにまたがるセッションや状態を管理する。
  • カスタムクエリでデータベースアクセスを最適化する。
  • よく使用されるレンダリングロジックを複数の異なる部分で再利用する。

カスタムクラスベースビューは以下のように記述されます。

from django.views.generic import View
from django.shortcuts import render
from . import models

class ProductSalesView(View):

    def get(self, request):
     
        # Custom data processing 
        sales = get_sales_data()
        
        return render(request, "sales.html", {"sales": sales})

    def post(self, request):

        # Custom form handling
        form = SalesSearchForm(request.POST)  
        if form.is_valid():
            results = models.Sale.objects.filter(date__gte=form.cleaned_data['start_date'])
            context = {"results": results}
            return render(request, "search_results.html", context)
            
        # Invalid form handling
        errors = form.errors
        return render(request, "sales.html", {"errors": errors})

ここではカスタムの get ハンドラーと post ハンドラーを使用することで、複数のリクエスト間で既存のハンドラーを拡張できるようにしています。

それぞれの種類のビューの使用

関数ベースビューとクラスベースビューはどちらも、ビューロジックの複雑さとニーズに応じて使い分けることができます。

主な違いは、次のようなクラスベースビューの特徴にあります。

  • サブクラス化をしたり親の動作を継承したりすることで、再利用を促進する。
  • 複数のリクエストにまたがる状態管理に最適である。
  • より体系的な構造と厳格なルールを提供する。

以下のようなユースケースで使用できます。

  • 複雑なレンダリングロジックを使用するダッシュボードページ。
  • 動的なデータを表示する一般公開ページ。
  • コンテンツ管理用の管理者ポータル。
  • データベースモデルを必要とするリストまたは詳細ページ。

その一方、関数ベースビューには次のような特徴があります。

  • より単純で、比較的少ないコードで作成できる。
  • Python 開発者が理解しやすい。
  • 非常に柔軟で、制約が少ない。

以下のようなユースケースがあります。

  • アイデアのプロトタイピング。
  • 単純な CRUD 操作またはデータベースビュー。
  • ランディングページまたはマーケティングページ。
  • ウェブリクエストを処理するための API エンドポイント。

要するに、関数ベースビューは柔軟であり、単純明快で、理解しやすくはあるものの、 ケースが複雑であるほど、より多くの再利用不可能なコードを作成する必要があります。

Django のクラスベースビューは構造化を実現し、再利用できるものの、理解や実装、そしてデバッグは比較的困難です。

ビューと URL

すでに述べたように、Django のビューはテンプレートのレンダリング方法を決める関数またはクラスです。 それぞれのビューは特定の URL パターンにリンクしており、受信したリクエストを適切な場所に誘導します。

アプリケーションのフローを効果的に管理するには、ビューと URL の関係を理解することが重要です。

各ビューは Django アプリの urls.py ファイルで定義されている URL パターンに対応しています。 この URL マッピングにより、ユーザーがアプリケーション内の特定のアドレスに移動する際に Django が実際にどのビューを呼び出すべきかを認識できるようになっています。

単純な URL の構成を見てみましょう。

from django.urls import path
from .views import BookListView

urlpatterns = [
    path('books/', BookListView.as_view(), name='book-list'),
]

この構成では、ユーザーが /books/ にアクセスすると、BookListView が呼び出されて書籍のリストがレンダリングされます。 URL を明確にビューにマッピングすると、コードベースを読みやすく、より整理された状態にすることができます。

PyCharm による URL 管理の単純化

アプリケーションの規模が大きくなるほど、Django でのエンドポイントの管理と可視化は困難になります。 PyCharm はアプリのすべての URL パターン、リンク先のビュー、および HTTP メソッドをまとめて表示する Endpoints(エンドポイント)ツールウィンドウでこれを解決します。 この機能を使用すると、プロジェクト内のすべてのエンドポイントをリスト表示できるため、どのビューが特定の URL に関連付けられているかを追跡しやすくなります。

複数の urls.py ファイルを検索する代わりに、ワンクリックするだけで瞬時に対応するビューを特定し、そこに移動することができます。 これは、URL 構成が複数のファイルにまたがっている大規模な Django プロジェクトや、コンテキストを素早く明確にすることが重要なチームで作業する際に特に役立ちます。

さらに、Endpoints(エンドポイント)ツールウィンドウではテーブル形式のインターフェースですべてのエンドポイントを可視化できます。 それぞれの行には特定のエンドポイントのビューの URL パス、HTTP メソッド(GETPOST など)、関連するビュー関数またはクラスが表示されます。

この機能は生産性を向上させるだけでなく、コード内の移動操作も改善するため、欠落または不足している URL パターンを簡単に発見することができます。 このレベルの可視性はルーティングの問題をデバッグしたり、新しい開発者をプロジェクトに迎える場合に非常に役立ちます。

Endpoints(エンドポイント)ツールウィンドウとその活用方法に関する詳細は、こちらの動画をご覧ください。

Django ビューの使用に関するベストプラクティス

以下は、十分に構造化された管理可能なビューの作成に役立つガイドラインです。

ビューの目的を維持する

ビューの目的は、リクエストの処理、データの取得、テンプレートへのデータの受け渡し、およびフロートとリダイレクトの管理に特化する必要があります。 込み入ったビジネスロジックや複雑な処理は、モデルのメソッドや専用のサービスクラスなどの他の場所で実装すべきです。

ただし、モデルに過剰にロジックを詰め込んでしまうと、Django に「ファットモデル」というアンチパターンが発生する可能性があります。 Django のビューに関するドキュメントには、モデルを適切に構造化するための詳細なインサイトが掲載されています。

ビューとテンプレートを軽量に維持する

ビューとテンプレートのどちらも軽量であるのが最善です。 ビューはリクエストの処理とデータの取得を担うべきで、テンプレートは最小限のロジックで表示することに特化すべきです。

複雑な処理は管理とテストを容易にするため、テンプレート外の Python で実装すべきです。 その詳細については、Django のテンプレートのドキュメントをご覧ください。

データベースクエリを分解する

データベースクエリをビューに直接書くのではなく、個別のモデルマネージャーやリポジトリに抽出すると、冗長性を軽減できます。 データベース操作の効果的な管理方法については、Django のモデルのドキュメントをご覧ください。

可能な限り汎用クラスベースビューを使用する

Django の DetailViewListView などの汎用クラスベースビューは、大量のコードを書くことなく再利用できます。 これらのビューを作成し直さずに再利用することで、時間をより有効に活用できます。 汎用ビューのドキュメントは、この機能を理解するのに大いに役立つリソースです。

関数ベースビューは単純なケースに適切

API を提供するような基本的なビューには、クラスよりも関数の方が効果的です。 複雑なクラスベースビューは込み入った UI のフローに利用しましょう。 ビューの記述に関するドキュメントには、役に立つ例が記載されています。

ルートと URL をクリーンに構造化する

ルートとビューのハンドラーをアプリ内で機能別にグループ化して整理しましょう。 こうすることで、ソースの検索と移動操作がより簡単になります。 URL 構成の構造化に関するベストプラクティスについては、Django の URL ディスパッチャーのドキュメントをご覧ください。

次のステップ

Djago のビューについて基本的な理解を得たら、フレームワークとその他の次のステップをさらに掘り下げたくなるかと思います。

  • Django の学習方法」ブログ記事で Django の知識をレベルアップしましょう。この記事は初心者の方や、専門知識を更新したい方に最適です。
  • Django の現状」で Django 開発の最新トレンドをご覧ください。さらにインスピレーションが得られるかもしれません。

PyCharm での Django のサポート

PyCharm Professional は最高クラスの Django 開発用 IDE です。 Django に特化したコーディング支援、プロジェクト全体にわたる移動操作とリファクタリング、および Django テンプレートの完全サポートにより、コーディングを高速化できます。 ワンクリックでデータベースに接続し、TypeScript、JavaScript、およびフロントエンドフレームワークで作業できます。 PyCharm は初期状態で Flask と FastAPI もサポートしています。

より優れたアプリケーションを作成し、コーディング作業を合理化しましょう。 今すぐ PyCharm を使い始め、手間のかからない Django の開発をぜひご体験ください。

オリジナル(英語)ブログ投稿記事の作者:

Evgenia Verbina

Evgenia Verbina

image description