【Django入門2】Djangoの全体像・ファイル構成・動作の仕組み

Djangoの全体像とDjangoのウェブアプリが動作する仕組みについての解説ページアイキャッチ

このページにはプロモーションが含まれています

このページでは Django の全体像やファイル構成、さらには動作の仕組みについて解説していきたいと思います。特に Django 初心者の方向けの解説となります。

下記ページで解説しているように、Django はウェブアプリケーションフレームワークの1つであり、Django の利用により効率的なウェブアプリ開発を実現することができます。

【Django入門1】Djangoとは?

こういったメリットもある一方で、Django は慣れるまでが大変であるというデメリットもあり、ある程度 Django に慣れるまではむしろ「開発しにくい」と感じることも多いと思います。

そこで、このページでは、Django に慣れるための知識として Django の全体像や動作の仕組みについて解説をしていきたいと思います。

もちろん、Django は大量の Python スクリプトから構成され、さらに多種多様な機能を提供するフレームワークですので、このページのみで Djnaog 全てについて語り尽くすことはできません。

ただ、このページを読むことで Django の全体像がボヤッとでも掴むことができ、Django での開発時に「何をやっているか分からない…」という状態は脱却できるようになるのではないかと思います。

是非最後まで読んでみてください!

Django の全体像

では、Django の全体像について解説していきます。

Django = ウェブアプリケーションフレームワーク

まず、Django はウェブアプリケーションフレームワークの1つになります。

こういったフレームワークを利用することで、ウェブアプリを効率的に開発することができるようになります。フレームワークがどういったものであるかや、フレームワークを利用することでアプリ開発が効率的になる理由などは下記で解説していますので、詳しく知りたい方は下記ページを参照していただければと思います。

【Django入門1】Djangoとは?

スポンサーリンク

ウェブアプリ公開時のソフトウェア構成

ウェブアプリはウェブブラウザから利用可能なアプリであり、サーバーマシン上からウェブアプリを公開することになります。ウェブアプリがユーザーのウェブブラウザから利用される際のサーバーマシン上のソフトウェアの構成例は下の図のようになります。

ウェブアプリ公開時のソフトウェア構成の一例

この構成において、ユーザーからウェブアプリが利用される際の「サーバーマシン上の各ソフトウェアの動作」について簡単に説明します。

ウェブサーバー等がリクエストを受け取る

まず、ユーザーはウェブアプリを利用するために、ウェブブラウザでウェブアプリのページ(画面)を表示するための URL の指定を行います。この URL は、ウェブブラウザのアドレスバーに入力したり、リンクをクリックしたりすることで指定することができます。また、URL とはウェブ上のページを特定するための住所みたいなものであると考えていただければ良いかと思います。

ウェブアプリのURLを指定する様子

ウェブブラウザで URL の指定を行えば、その URL に対応したサーバーマシンのウェブサーバーに HTTP リクエストが送信されます。HTTP リクエストとはウェブサーバーへの要求です。

リクエスト自体はデータであり、具体的にどんな要求であるかはそのデータに記述されています。この HTTP リクエストを送信することで、例えば「画面・ページの表示」や「データの送信」等をウェブサーバーに対して要求することができます。まずは、ウェブブラウザから送信される HTTP リクエストはウェブアプリの画面(ページ)表示を行う要求として考えていきたいと思います。

ウェブブラウザからウェブサーバーにリクエストが送信される様子

ウェブアプリがリクエストを受け取りレスポンスを返却する

このリクエストを受け取ったウェブサーバーは、AP サーバーにリクエストを送信し、さらに AP サーバーはウェブアプリの実行を行います。この際、ウェブアプリは AP サーバーからリクエストを受け取り、そのリクエストに応じた処理を行ないます。そして、その処理の結果をレスポンスとして AP サーバーに返却します。

ウェブサーバーからAPサーバーに、さらにAPサーバーからウェブアプリにリクエストが渡され、さらにウェブアプリがレスポンスをAPサーバーに返却する様子

このレスポンスには、リクエストの成功・エラーを表す「ステータスコード」や、ウェブブラウザにページを表示するための HTML データや CSS データ・画像データなどの「ボディ」が含まれることになります。HTML はウェブブラウザに何の要素を表示するかを指定するデータで、CSS は各要素の見た目を指定するためのデータとなります。

レスポンスのデータ構造

例えばですが、Twitter のようなウェブアプリであれば、ユーザーのツイート履歴一覧のページを表示したいというリクエストを受け取った場合、ウェブアプリはそのユーザーのツイート履歴の一覧を表示するための HTML を生成し、それをボディとするレスポンスを AP サーバーに返却することになります。

またウェブアプリでは、扱うデータはデータベースに保存されることが多いです。上記の例であれば、ユーザーがツイートした情報がデータベースに保存されていることになります。データベースに保存されたデータをウェブアプリの画面(ページ)に表示したいような場合は、データベースからデータを取得し、そのデータを反映したレスポンスを生成するようにウェブアプリが動作することになります。

ウェブアプリがデータベースからデータを取得し、その結果を反映させたHTMLをボディとしてレスポンスを返却する様子

さらに、ウェブサーバーは AP サーバーからレスポンスを受け取り、それをリクエスト送信元のウェブブラウザに返却します。これにより、ウェブブラウザは HTML 等のデータを受け取り、それをウェブブラウザ上にページとして描画することで、ユーザーがウェブアプリのページを閲覧することができることになります。

ウェブサーバーからウェブブラウザにレスポンスが返却される様子

前述で示したサーバーマシン上のソフトウェア構成は一例であり、異なる構成の場合もあるので注意してください。ただし、異なる構成であっても、ウェブアプリがリクエストを受け取り、リクエストに応じた処理を行なってレスポンスを生成して返却するという点は同じになります。

そのため、開発者は、リクエストに応じた処理を行なってレスポンスを生成して返却するようにウェブアプリを開発していく必要があることになります(特に Django でウェブアプリを開発する際、レスポンスのボディを生成することが重要になります)。

具体例を挙げると、例えば Twitter を真似たウェブアプリを開発するのであれば、ユーザーのツイート履歴一覧を表示したいというリクエストを受け取った際には、そのユーザーのツイート履歴一覧をデータベースから取得し、そのツイート履歴一覧を埋め込んだ HTML を生成してレスポンスとして返却するような動作を実現する必要があります。

リクエストの種類

また、ここまでは基本的に「ページを表示するリクエスト」に対する動作を説明してきましたが、「データを送信するリクエスト」の場合も同様で、ウェブアプリはリクエストを受け取り、そのリクエストに応じた処理を行なってレスポンスを生成して返却することになります。

ただ、リクエストの内容が異なるため、ウェブアプリ内で行う「リクエストに応じた処理」も異なることになります。どういう処理を行うのかはウェブアプリによって異なりますが、データを送信するリクエストの場合、受け取ったデータをデータベースに保存する処理を行うケースが多いと思います。そして、保存成功したことを伝えるための HTML を生成して返却するケースが多いです。

ウェブアプリがデータベースにデータの保存を行う様子

いずれにせよ、上位側のサーバーからリクエストを受け取り受け取ったリクエストに応じた処理を行い、さらにレスポンスを上位側のサーバーに返却することがウェブアプリの基本的な動作であると考えると良いと思います。

Django で開発するウェブアプリの構成

ここまでは、他のサーバーソフトウェアとの関係性を示す形でウェブアプリの全体像を解説してきました。

ここからは、ウェブアプリに注目し、Django で開発するウェブアプリの構成に説明していきたいと思います。

ウェブアプリに注目する様子

ウェブアプリの構成

Django で開発するウェブアプリの構成を簡単に示したものが下図となります。

Djangoで開発するウェブアプリの構成を示す図

Django を利用して開発するウェブアプリは大きく2つの部分から構成されます。1つ目はフレームワーク、つまり Django であり、2つ目はプロジェクトになります。1つ目の部分は単に Django と記しても良いかもしれませんが、フレームワークであることを意識していただきたいため、Django フレームワークと記していきたいと思います。

この2つは役割が大きく異なり、Django フレームワークの役割は「ウェブアプリで共通的な動作を実現する」ことであり、プロジェクトの役割は「開発するウェブアプリ特有の動作を実現する」ことになります。

Django フレームワーク

前者の Django フレームワークは、下記ページでも解説しているとおり、ウェブアプリにおける共通的な機能や構造を提供する枠組みとなります。

【Django入門1】Djangoとは?

例えばウェブアプリではデータベース操作や認証機能を備えているものが多いので、そういったウェブアプリで一般的に共通して利用される機能が Django フレームワークから提供されるようになっています(下図では4つの機能のみを記載していますが、他にも多くの機能が存在します)。

フレームワークがウェブアプリで共通的に利用される機能を提供する様子

つまり、Django フレームワークの機能を利用するだけで、上記のようなウェブアプリで共通となる処理や動作を実現することができます。この Django フレームワークは Django をインストールすることで自動的に PC 内に構築され、Django で開発するウェブアプリにおいて共通的に利用されるものになります。

さらに、この Django フレームワークの機能はプロジェクト内のファイルから利用することができます。ですので、例えばデータベース操作の処理を自身で実装しなくても、Django のフレームワークの機能を利用するだけでデータベース操作を実現することができます。

プロジェクトからDjangoフレームワークの機能を利用する様子

プロジェクト

ただし、どういう機能をどのように利用するかは開発者自身が考え、それに応じてプロジェクト内のファイルを実装していく必要があります。例えばデータベースにデータを保存すること自体は Django フレームワークの機能を利用すれば実現できますが、何のデータを保存するかは開発者が決め、それに応じて実装を行う必要があります。

例えば、Twitter のようなウェブアプリを実現したいのであればツイートや「いいね!」の情報をデータベースに保存する必要がありますし、CookPad のようなウェブアプリを実現したいのであればレシピを保存する必要があります。

そして、この Django フレームワークから提供される機能の利用の仕方を工夫することによって、他のウェブアプリとは異なる機能や動作を実現することができるようになります。そして、それを実装する部分がプロジェクトであり、つまりはプロジェクトは他のウェブアプリとの差別化を図るための、ウェブアプリ特有の機能を実現する部分となります。

プロジェクトの役割を示す図

Django フレームワークとプロジェクトにおけるファイル位置の関係

ここで1点補足しておくと、ウェブアプリの構成が下の図のようになると考えられるのは「動作的な構成」で考えた場合となります。

フレームワークがウェブアプリで共通的に利用される機能を提供する様子

実際には、Django フレームワークとプロジェクトのファイルは別々の場所にあるので注意してください。

Django フレームワークを構成するファイルは Django 自体のインストール先のフォルダ内に存在します。この Django フレームワークが存在する位置に関しては環境等によって異なるので一概には言えないのですが、例えば私の環境であれば下記フォルダ以下に Django フレームワークを構成するファイルが存在しています。

/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/django

それに対し、プロジェクトのファイルは後述の プロジェクトの構成 で紹介するコマンドにより生成される「プロジェクト名」のフォルダ内に存在します。このフォルダは自身で好きな場所に作成することができます。例えばドキュメントフォルダの下やデスクトップに作成することが多いと思います。

したがって、Django フレームワークとプロジェクトのファイルは全く別々の場所に存在することが多いです。

Djangoフレームワークとプロジェクトの存在する位置が異なることを示す図

ですが、動作的に考えると、プロジェクト内のファイルから Django フレームワーク内のファイルで定義される関数を実行したり、逆に Django フレームワーク内のファイルからプロジェクト内ののファイルで定義された関数が実行されたりするため、先ほど示した Django フレームワークがプロジェクトを囲う形の構成がしっくりくるのではないかと思います。

Django の開発用サーバー

ここで1つ Django が提供する重要な機能を紹介しておきます。それが開発用サーバーになります。

開発用サーバーとは

前述の通り、ウェブアプリは他のサーバーから実行されることで動作することになります。前述では AP サーバーからウェブアプリが実行される構成を紹介しましたね!

ただ、ウェブアプリの公開時に他のサーバーを用意するのは仕方ないとしても、お試しでのウェブアプリの実行や、開発時の動作確認ためにわざわざ他のサーバーを用意するのは面倒です。

この面倒さを解消するため、Django では開発用サーバーが用意されており、これが前述のウェブサーバーや AP サーバー等の代わりとなるようになっています。したがって、お試しや動作確認のためにウェブアプリを動作させる際には、他のサーバーを用意する必要がなく、Django さえインストールしておけば開発用サーバーを利用してウェブアプリを動作させることができます。

開発用サーバー利用時のソフトウェア構成

この開発用サーバーを利用した時の構成は下の図のようになります(開発用サーバーは Django フレームワークの一部と言っても良いかもしれませんが、このページではこれらを別のものとして扱っていきたいと思います)。

開発用サーバーを利用した際のウェブアプリの動作環境

開発用サーバーはウェブアプリの動作確認用に利用するサーバーであり、この場合は開発用 PC 上で動作するウェブアプリからリクエストを送信することが多いため、上の図のように1つの PC 上で動作する構成を示しています。

開発用サーバーを利用する構成においては、ウェブブラウザ等のクライアントからの「リクエストの受信」クライアントへの「レスポンスの返却」は開発用サーバーの役割となります。リクエストを受け取った際には、開発用サーバーはウェブアプリを実行し、この際にウェブアプリへリクエストを渡します。そして、ウェブアプリから返却されたレスポンスをウェブブラウザ等のクライアントに返却してくれます。

そのため、Django では開発用サーバーの起動をしておくだけで「開発中のウェブアプリの動作確認」を行うことができることになります。基本的には、Django を利用したウェブアプリ開発においては、上図に示すような開発用サーバーを利用した構成で開発を行なっていくことになります。ただし、開発用サーバーは、あくまでも Django で開発するウェブアプリの動作確認用に利用されるサーバーであり、ウェブアプリ公開時には利用されません。

そのため、ウェブアプリが完成して公開する際には、ウェブアプリ公開時のソフトウェア構成 で示したようなウェブサーバーや AP サーバー等を利用する構成(本番環境)に移行する必要があります。

スポンサーリンク

プロジェクトの構成

さて、先ほど Django で開発するウェブアプリは Django フレームワークとプロジェクトの2つから構成されると説明しました。

前者の Django フレームワークに関しては、基本的にインストールされたものをそのまま利用することになり、開発者は主に、後者のプロジェクト内のファイルを編集していくことでウェブアプリを開発していくことになります。

MEMO

基本的に Django フレームワークを直接変更することはありませんが、プロジェクト内のファイルによって Django フレームワークの動作の設定を行うことが可能です

これの詳細に関しては settings.py で解説します

次は、このプロジェクト内のファイル・フォルダ構成について解説していきます。

プロジェクトに注目する様子

プロジェクト内には下図のようなファイルやフォルダが存在します。これらのファイルは後述で紹介するコマンドを実行することで自動的に生成されるものになります。基本的には、これらのファイルを変更することでウェブアプリを開発していくことになりますが、別途ファイルを新規作成し、そのファイルの中でクラスを定義したり関数を作成したりするようなことも可能です。

プロジェクトのフォルダ・ファイル構成を示す図

コマンドで自動生成される各フォルダ・各ファイルの役割を簡単に記すと下記のようになります。

  • manage.py:Django 向けのコマンドを実行するスクリプトファイル★
  • プロジェクト名 フォルダ:プロジェクトの設定ファイルを格納するフォルダ★
    • __init__.py:Python に プロジェクト名 フォルダをパッケージとして認識させるためのファイル
    • settings.py:Django フレームワークの動作を設定するファイル★
    • urls.py:Django フレームワークの動作を設定するファイル(URL と実行する関数の関連付け)★
    • wsgi.py:サーバーとのインターフェースを定義するファイル(WSGI 用)
    • asgi.py:サーバーとのインターフェースを定義するファイル(ASGI 用)
  • アプリ名 フォルダ:アプリを構成するファイルを格納するフォルダ★
    • __init__.py:Python に アプリ名 フォルダをパッケージとして認識させるためのファイル
    • apps.py:アプリ独自の設定ファイル
    • views.py:MTV における View を構成するファイル★
    • models.py:MTV における Model を構成するファイル★
    • admin.py:管理画面用の設定ファイル★
    • tests.py:テスト用のファイル
    • migrations フォルダ:マイグレーションの設定ファイルを格納するフォルダ★
      • __init__.py:Python に migrations フォルダをパッケージとして認識させるためのファイル

コマンドによって様々なファイルが自動生成されますが、まず Django 初心者の方が意識すべきファイルやフォルダは★マークの付いたものになると思います。

例えば __init__.py が複数のフォルダ内に存在しますが、これらは Python にパッケージ認識させるためのものであり、基本的にはそのまま利用して良いです。

また、wsgi.pyasgi.py は AP サーバーや開発用サーバーからウェブアプリを実行するためのオブジェクトを定義するもので、これらもまずは変更せずに開発を始めて良いと思います(ウェブアプリ公開時などに見直す必要はあると思います)。

そのため、ここからは★マークのついたフォルダやファイルについて詳細な説明をしていきたいと思います。

manage.py

manage.py は Django 向けのコマンドを実行するために使用する Python スクリプトファイルになります。

例えば、Django の開発用サーバー で Django には開発用サーバーが用意されており、これを利用することで簡単にウェブアプリの動作確認ができると説明しました。

この開発用サーバーを起動するためには、Django 向けのコマンドである runserver を実行する必要があります。このような Django 向けのコマンドを実行するためのファイルが manage.py であり、引数として コマンド名 を指定した状態で manage.py を実行することで Django 向けのコマンドが実行されることになります。

% python manage.py コマンド名

例えば開発用サーバーを起動するためには、コマンド名runserver を指定して実行します。

これにより開発用サーバーが起動し、ウェブブラウザからウェブアプリの動作確認を行うことができるようになります。

他にも Django 向けのコマンドは数多く存在しており、特に下記のコマンドに関しては Django でのウェブアプリ開発時にはほぼ必ず使用することになると思います。

  • startappアプリ名 フォルダを生成する
  • makemigrations:マイグレーションの設定ファイルを生成する
  • migrate:上記設定ファイルに基づいてマイグレーションを実行する

その他のコマンドについては、下記のように引数なしで manage.py を実行することで確認することができます。

% python manage.py

プロジェクト名 フォルダと アプリ名 フォルダ

また、プロジェクトの直下には2つのフォルダが存在しており、これらが プロジェクト名 フォルダと アプリ名 フォルダとなります。

次は、プロジェクトと プロジェクト名 フォルダ、アプリ名 フォルダの作り方や関係性について解説していきます。

プロジェクトのフォルダ・ファイル構成を示す図

「プロジェクト」と「プロジェクト設定」の作り方

プロジェクト自体と、その直下に存在する プロジェクト名 フォルダ、さらには manage.py に関しては、下記コマンドを実行することで自動的に生成されるフォルダやファイルとなります。

% django-admin startproject プロジェクト名

ちなみに、django-admin は Django インストール時に一緒にインストールされるコマンド(実行可能ファイル)になります。

上記コマンドを実行することで、コマンドを実行した位置のフォルダ直下に プロジェクト名 のフォルダが生成されます。このフォルダ以下のファイル群を、このページでは「プロジェクト」と読んでいます。

さらに、そのプロジェクトの中には manage.py と、もう1つの プロジェクト名 のフォルダが生成されることになります。

startprojectで生成されるフォルダ・ファイル群を示す図

つまり、プロジェクト名 のフォルダの中に プロジェクト名 のフォルダが存在することになります。2つの プロジェクト名 のフォルダがあって、これだとちょっと説明がややこしくなるので、プロジェクト名 のフォルダの中に存在する プロジェクト名 フォルダのことを、ここからは「プロジェクト設定」と呼ばせていただきたいと思います。

「アプリ」の作り方

さて、上記コマンドを実行することでプロジェクトの中に manage.py が生成されるため、このファイルを利用して Django 向けのコマンドの実行を行うことが可能となったことになります。

プロジェクトにおける アプリ名 フォルダ以下のフォルダやファイルに関しては、Django 向けのコマンドである startapp を実行することで生成することができます。具体的には、下記のコマンドを実行することで、プロジェクト直下に アプリ名 フォルダが生成されることになります。このフォルダ以下のファイルの集まりをアプリと呼ばせていただきます。

% python manage.py startapp アプリ名

このアプリ部分こそが、開発するウェブアプリ特有の動作や機能を実現するためのものであり、これらを変更することで世の中に存在しない新しいウェブアプリを開発していくことになります。

startappコマンドで生成されるフォルダ・ファイル群

「プロジェクト」・「プロジェクト設定」・「アプリ」の関係

さて、ここで3種類のフォルダが生成されたことになりますが、前述の通り、開発するウェブアプリ特有の動作や機能を実現していくための部分が「アプリ」となります。この「アプリ」はプロジェクト内に複数存在させることもでき、1つの「アプリ」で1つのウェブアプリとして仕上げることもできますし、複数の「アプリ」を連携動作させることで1つのウェブアプリとして仕上げていくこともできます。

プロジェクトとプロジェクト設定とアプリの関係性1

それに対し、「プロジェクト設定」は Django フレームワーク側の動作を設定するためのファイル群となります。言い方を変えれば、プロジェクト内の「アプリ」共通の設定を行う部分とも言えます。プロジェクト内の「アプリ」から Django フレームワークが提供する機能を利用する際、その機能は「プロジェクト設定」での設定に従って動作することになります。

プロジェクトとプロジェクト設定とアプリの関係性を示す図2

例えばですが、「プロジェクト設定」の settings.py では使用するデータベースの設定を行うことができます。settings.py のデフォルト設定では使用するデータベースとして「SQLite3」が指定されていますが、settings.py を変更して使用するデータベースに「MySQL」を指定すれば、プロジェクト内の「アプリ」から Django フレームワークのデータベース操作機能を利用した際、データベース操作機能はデータベースとして MySQL を使用するようになります。

プロジェクト設定によってDjangoフレームワークで使用するデータベースを変更する様子

さらに、「プロジェクト」は「プロジェクト設定」と「アプリ」を集めたものとなります。前述の通り、プロジェクト内の「アプリ」は複数存在しても問題ありません。

ただし、「プロジェクト設定」はプロジェクト内の「アプリ」から利用される Django フレームワークの機能の設定を行うものであり、Django フレームワークの機能の設定をアプリごとに変更したい場合は、それらの「アプリ」は別々の「プロジェクト」に分けて開発した方が良いと思います。これは、「プロジェクト設定」での設定は Django フレームワークの機能に対する設定であり、プロジェクト内の「アプリ」全てから利用される際に共通に適用される設定となってしまうからです。

スポンサーリンク

settings.py

続いてプロジェクト設定内の各ファイルについて説明していきます。まずは settings.py について説明します。

settings.py の役割

settings.pyDjango フレームワークの設定を行うファイルとなります。プロジェクト内のアプリ共通の設定を行うこともできます。

例えば、データベースにデータを保存する場合はプロジェクトから Django フレームワークのデータベース操作機能を利用することになります。この時、Django フレームワークのデータベース操作機能は SQLite3 のデータベースにデータを保存することになります。

この理由は、settings.py でデータベースとして SQLite3 を利用することが設定されているからです。具体的には下記部分がその設定となっています。

settings.pyでのDATABASES設定
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

このように、Django フレームワークは settings.py での設定に従って動作します。

違う見方をすれば、settings.py の設定を変更してやることで、Django フレームワークの動作を変化させることができると言えます。例えば上記の DATABASES を変更してやることで、Django フレームワークで使用するデータベースを MySQL や PostgreSQL に変更することができます。

settings.pyによってフレームワークの動作が変化する様子

他にも settings.py で設定可能な項目はたくさんあります。settings.py で設定可能な項目の調べ方は下記ページで解説していますので、詳しく知りたい方は下記ページをご参照ください。

Djangoのsettings.pyで設定可能な項目とデフォルト値の調べ方の解説ページアイキャッチ 【Django】settings.py での設定可能項目やデフォルト値の調べ方

settings.py でのアプリの登録

Django でウェブアプリを開発する際、settings.py で必ず行う必要のある設定が「アプリの登録」になります。前述の通り、Django フレームワークの機能はアプリ内のファイルから利用することもできますが、逆にアプリは Django フレームワークから利用されるものでもあります。

例えばですが、アプリ内の models.py は起動時に Django フレームワークから読み込まれることによって、他のファイルから models.py で定義されたモデルを利用できるようになります。

また、ウェブアプリはリクエスト受け取ってレスポンスを返却するアプリとなりますが、Django で開発するウェブアプリにおいて最初にリクエストを受け取るのは Django フレームワークです。その後、Django フレームワークからアプリが利用されて(アプリ内で定義される関数が実行されて)、レスポンスのデータが生成されることになります。

ただ、このような Django フレームワークからのアプリの利用が実現できるのは Django フレームワークがそのアプリを認識しているからであって、アプリを認識していなければアプリ内のファイルの読み込みは行われません。

そのため、アプリの存在を Django フレームワークに認識させる必要があります。このために行うのが settings.py でのアプリの登録になります。このアプリの登録は、settings.pyINSTALLED_APPS にアプリ名 or アプリの apps.py で定義されるクラスを指定する必要があります。

例えば下記は、'testapp' という名前のアプリを登録する例となります(1行目に追記しています)。

settings.pyでのINSTALLED_APPSの設定
INSTALLED_APPS = [
    'testapp', # 'testapp.apps.testapp'でも可
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

これによって Django フレームワークが登録されたアプリを認識し、そのアプリが Django フレームワークから利用されるようになります。上記では1つのアプリのみを登録していますが、複数のアプリを登録することも可能です。

また、実際に settings.py を確認してみると分かると思いますが、自動生成された時点で settings.pyINSTALLED_APPS にはデフォルトで複数のアプリが登録されていることになります。

例えば django.contrib.admin は Django フレームワークにおける管理画面機能を実現するアプリであり、これがINSTALLED_APPS に登録されているため、管理画面を自身で開発しなくても管理画面の機能を利用することができるようになっています。また、django.contrib.auth は Django フレームワークにおける認証機能を実現するアプリとなり、認証機能を自身で開発しなくても認証機能を利用することができるようになっています。

こういったデフォルトで登録が行われているアプリも存在することや、こういったアプリと連携動作して自身が開発するアプリが動作し、それによって1つのウェブアプリが実現されていくということも覚えておくと良いと思います。

urls.py

settings.py 同様に、urls.py も Django フレームワークの設定を行うファイルとなります。ただし、urls.py は「Django フレームワークがリクエストを受け取った際に実行する関数」の設定に特化した設定ファイルとなります。

もう少し噛み砕いて言えば、「リクエストされた URL」と「実行する関数」との関連付けを行う設定ファイルになります。

ウェブアプリ公開時のソフトウェア構成 などでも説明したように、ウェブアプリはリクエスト受け取り、リクエストに応じた処理の実行やレスポンスの返却を行うアプリになります。

urls.pyの説明図1

ウェブアプリにおいて、このリクエストを最初に受け取るのは Django フレームワークになります。そして、基本的には Django フレームワークがアプリ内の関数やメソッドを実行し、アプリ内の関数やメソッドがレスポンス(の特にボディ部)を生成し、その結果を Django フレームワークが受け取ります。さらに、それをレスポンスとしてリクエスト元に返却していくことになります。

MEMO

CSS ファイルや画像ファイルなどがリクエストされる場合はもう少し異なる動作となります

では、Django フレームワークから実行される「アプリ内の関数やメソッド」とは具体的に何になるのでしょうか?

実は、これについてはプロジェクトやアプリ作成時には決まっておらず、リクエストを受け取った時に Django フレームワークから実行して欲しい関数やメソッドを開発者が設定しておく必要があります。そして、この設定先のファイルが urls.py となります。

もう少し詳細を説明すると、リクエストには「リクエスト先の URL」が指定されることになりますので、その URL に応じて「実行して欲しい関数」を指定するのが urls.py となります。urls.py を設定しておくことで、Django フレームワークがリクエストを受け取ったときに urls.py の設定に従って関数やメソッドを実行してくれるようになります。

urls.pyの説明図2

下記は urls.py の設定例となります。下記はアプリが testapp であるとし、さらに testapp の中の views.pyindexsignuplogin 関数が定義されている前提の例となります。

urls.pyの設定例
from django.contrib import admin
from django.urls import path
from testapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('testapp/', views.index, name='index'),
    path('testapp/signup/', views.signup, name='signup'),
    path('testapp/login/', views.login, name='login'),
]

例えば、上記 urls.py における urlpatterns の最後の行の要素は、リクエスト先の URL がルートパス指定で「/testapp/login/」である場合に「views.py で定義している login 関数」を実行して欲しいという設定になります。

この urls.py を読み込んだ Django フレームワークは、URL がルートパス指定で「/testapp/login/」となっているリクエストを受け取った際に「views.py で定義している login 関数」を実行してくれるようになります。

urls.pyの説明図3

このように、urls.py を適切に設定しておけば Django フレームワークが urls.py に従って実行する関数やメソッドを振り分けてくれるようになります。ですので、後は Django フレームワークから実行される関数やメソッドでレスポンスを生成して返却するようにすれば、ウェブアプリとしての動作は完成することになります。

この urls.py に関しては次の連載となる下記ページで解説していますので、詳細に関しては下記ページをご参照ください。

Djangoのビューについての解説ページアイキャッチ 【Django入門3】ビューの基本とURLのマッピング

views.py

そして、先程の例のように、Django においては基本的に urls.py で実行される関数として views.py で定義される関数やメソッドが指定されることになります。

つまり、views.py は Django フレームワークから見たアプリの窓口と考えて良いでしょう。

また、下記ページで解説しているとおり、Django でのウェブアプリの構成は MTV モデルとなります。views.py は、その MTV モデルにおける V (View) を作り込むためのファイルとなります。

【Django入門1】Djangoとは?

この View にあたる views.py の最低限の役割は、Django フレームワークからリクエストを受け取り、Django フレームワークにレスポンスを返却することであることになります(問題があった場合に例外を発生させることも views.py の役割となります)。

もう少し具体的に言えば、urls.py で解説したように、urls.py の設定により Django フレームワークから views.py で定義された関数やメソッドが実行されるようになります。実行時には、引数としてリクエストのデータ(HttpRequest のサブクラスのオブジェクト)を受け取ることになりますので、そのリクエストのデータの内容に応じた処理を行い、さらに処理結果に応じたレスポンスのデータを返却するのが views.py で定義される関数やメソッドの役割となります。

このレスポンスのデータとは、HttpResponse クラス(もしくは HttpResponse のサブクラス)のオブジェクトになります。

views.pyで定義する関数・メソッドの役割を示す図

つまり、最も簡単な views.py で定義する関数は下記のようなものになります。

views.pyの簡単な例
from django.http.response import HttpResponse

def index(request):
    return HttpResponse('Hello World')

urls.py で上記の index 関数が実行されるように設定しておけば、リクエストを受け取った Django フレームワークから上記の index 関数が実行されるようになります。この時、引数として受け取ったリクエストのデータが渡されます。

さらに、index 関数は HttpResponse のコンストラクタを実行してオブジェクトを生成し、それを返却しています。そして、この返却されたオブジェクトを Django フレームワークが受け取って整形し、さらにそれを受け取った開発用サーバーがウェブブラウザに返却することになります。

これにより、ウェブブラウザ上に返却されたレスポンスに基づいたページが表示されることになります。index 関数では HttpResponse() の引数に 'Hello World' を指定しており、これがレスポンスのボディ部となってウェブブラウザには Hello World が表示されることになります。

このように、リクエストを受け取ってレスポンスを返却するという基本的な流れが成立しているため、一応これでウェブアプリとしての動作を満たすための views.py が完成していることになります。

ただし、上記の views.py だとウェブアプリを動作させてもウェブブラウザに毎回 Hello World と表示されるだけで全く面白みがありません。

もっと面白いウェブアプリを実現するためには、views.py で独自の処理やレスポンスの返却を行うようにする必要があります。

例えばログイン処理を行い、ログインユーザーに応じたレスポンスを返却したり、ユーザーから送信されたデータをデータベースに保存したり、その保存されたデータをうまく加工してレスポンスを返却したりするなどの処理が必要となります。

この views.py に関しても次の連載となる下記ページで解説していますので、詳細に関しては下記ページをご参照ください。

Djangoのビューについての解説ページアイキャッチ 【Django入門3】ビューの基本とURLのマッピング

スポンサーリンク

models.py

また、特にデータベースを利用する際に重要となるのが MTV における M (Model) であり、その Model を定義するのが models.py となります。

一般的なテーブルとレコード

まずは前提知識として、データベースについて少し解説しておきます。

データベースへのデータの保存は、テーブルに対してレコードを保存するという形で行われます。

テーブルとは下図の表のようなもので、レコードは下図の表における1行分のデータとなります。

データベースにおけるテーブルとレコードの関係を示す図

1つのデータベースには複数のテーブルが存在し、さらに1つのテーブルの中には複数のレコードが存在することになります。

また、上の図のテーブルには idusernameageheightweight という5つの項目の列が存在します。これらの項目は「フィールド(or カラム)」と呼ばれ、テーブル内の各レコードはテーブルの持つフィールドと同じフィールドを持つことになります。

データベースにデータを保存するためには、事前にテーブルをデータベース内に作成しておく必要があります。そして、その事前に作成しておいたテーブルに対してレコードを保存していくことになります。

テーブルに対してレコードを保存する様子

Django におけるテーブルとレコード

Django において、このテーブルはクラスとして扱われます。さらにテーブルにおける各レコードは、そのテーブルに対応するクラスのインスタンスとして扱われます。

Djangoにおけるクラスとテーブル、インスタンスとレコードの関係を示す図

具体的には、Django フレームワークでは Model というクラスが定義されており、このクラスを継承するサブクラスを models.py に定義しておけば、そのクラスがデータベースにおけるテーブルとして扱われます。さらに、このクラスにクラス変数としてフィールド(カラム)を持たせておくことで、そのクラス変数がテーブルのフィールド(列・カラム)として扱われるようになります。

例えば、下記のように models.py を定義すれば、Person クラスは usernameageheightweight というフィールドを持つことになります。また、各レコード(インスタンス)を区別することができるよう、自動的に id というフィールドも持つことになります。データベースのテーブルとして扱うためには Model クラスを継承する点があるという点に注意してください(この Modeldjango.db.models で定義されています)。

models.pyでの定義例
from django.db import models

class Person(models.Model):
    username = models.CharField(max_length=20)
    age = models.IntegerField()
    height = models.FloatField()
    weight = models.FloatField()

また、フィールドとして持たせるために定義するクラス変数においては、左辺でフィールド名、右辺でフィールドの種類を指定することになります。例えば文字列を扱いたいのであれば、上記の username のように右辺には CharField を指定します。また、age のように整数を扱いたいのであれば IntgerFieldheightweight のように浮動小数点数を扱いたいのであれば FloatField を指定します。

このように、フィールドで扱うデータに応じてフィールドの種類を使い分ける必要があります。

テーブルは別途用意する必要がある

また、単に models.py にクラスを定義しただけではデータベースにテーブルは作成されないという点に注意が必要となります。テーブルを作成するためには別途操作が必要であり、これに関しては migrations フォルダが関連性が高いので、migrations フォルダの解説を行う migrations で説明を行いたいと思います。

ここからは、事前にデータベースにテーブルが作成されていることを前提に、テーブルへのレコードの保存やテーブルからのレコードの取得について説明していきます。

テーブルへのレコード保存

前述の通り、クラスがテーブルであるのに対し、そのクラスのオブジェクト(インスタンス)がレコードの役割を果たします。このオブジェクトはクラスの持つものと同じフィールドを持っており、各フィールドに値をセットしたオブジェクトの保存を行えば、フィールドにその値がセットされたレコードが保存されることになります。

クラスとテーブル、インスタンスとレコードの関係図を示す図

このレコードの保存は、そのレコードに対応するオブジェクトに save メソッドを実行させることで実現することができます(Model のサブクラスでは、Model から save メソッドが継承されます)。

例えば、上記の Person であれば、ちょっと極端な例になりますが views.py の関数の中で次のようにオブジェクトを生成して保存を行うことで、上図のように Person クラスに対応するテーブルにレコードが保存されることになります(id に関しては自動で採番されることになります)。

レコードの保存例
from .models import Person
from django.http.response import HttpResponse

# Create your views here.
def index(request):
    person = Person()
    person.username = 'Hanako'
    person.age = 25
    person.height = 171.8
    person.weight = 67.3
    person.save()

    return HttpResponse('save a record')

上記の例では、index 関数が実行されるたびに毎回「id 以外に同じ値を持つレコード」がテーブルに保存されることになってしまいますが、後述で紹介するフォームから送信されたデータに基づきオブジェクトを生成し、それをレコードとして保存するようにすることで、ユーザーが入力した情報に基づいたレコードを保存するようなことも可能となります。

ユーザーがフォームから送信したデータに基づいたレコードがデータベースに保存される様子

テーブルへのその他の操作

また、今回は保存の例のみを示していますが、Model のサブクラスを利用することで、views.py の関数等からレコードを取得するようなことも可能となります。例えば Twitter のようなアプリであれば、ユーザーのツイートをデータベースにレコードとして保存しておき、特定のユーザーのツイートに対応するレコードを全て取得してレスポンスとなる HTML に埋め込めば、そのユーザーのツイート履歴を表示するようなこともできます。

このような処理の流れからも分かるように、MTV における Model に対応する models.py はデータベースのテーブルやレコードとなるクラスを定義し、さらにデータベースへの操作(レコードの保存など)を行うためのメソッドを提供することが役割となります。

そして、これらを利用してレコードの取得やレコードの保存等を行うのは主に MTV における View の役割となります。models.py で定義されたクラスを利用することで、データベースの操作を行います。

また、上記のようにレコードの取得や保存を行うだけでなく、レコードを更新したり削除したりすることもできます。これらも Model のサブクラスのオブジェクトにメソッドを実行させることで実現することができます。こういった Model の詳細については、今後の連載となる下記ページで解説しています。

モデルの解説ページアイキャッチ 【Django入門6】モデルの基本

migrations

続いて migrations フォルダについて解説していきます。

テーブルの用意の必要性

先ほど models.py の説明を行いましたが、models.py で定義されたクラスを利用してデータベースを操作する上でポイントになるのが、前述でも少し触れた「テーブルの用意」になります。

単に models.py にクラスを定義しただけではデータベースにテーブルは作成されません。作成されていないテーブルにレコードを保存したりしようとすると、例外が発生することになります。

例えば、先ほどレコードを保存する index 関数の例を紹介しましたが、index 関数の中で実行している save メソッドが正常終了するのは、models.py で定義された Person というクラスに対応するテーブルが事前に用意されている場合のみになります。テーブルが存在しない状態で save メソッドを実行すると例外が発生します。

存在しないテーブルにレコードが保存不可であることを示す図

マイグレーションの実行方法

このテーブルの用意を行うのがマイグレーションです。本来マイグレーションは異なるデータベース間でのデータの移行等を行う操作なのですが、この際にデータ移行先となるテーブルの作成や変更が行われることになります。

Django において、マイグレーションは下記の2つのコマンドを実行することで実現されます。

% python manage.py makemigrations
% python manage.py migrate

1つ目の makemigrations コマンドは、models.py に定義されたクラスに基づいてマイグレーションの設定ファイルを作成するためのコマンドになります。この設定ファイルは、この節の題名となっているアプリの migrations フォルダの下に作成されます。最初に makemigrations コマンドを実行した際には 0001_initial.py が作成され、その中に models.py に定義されたクラスの情報が記述されています。

migrationsフォルダの下にマイグレーションの設定ファイルが生成される様子

さらに、2つ目の migrate コマンドでは、makemigrations コマンドによって生成された設定ファイルに基づいてデータベースへのテーブルの作成や変更が行われることになります。まだデータベースにテーブルが存在しない場合はテーブルの作成が行われます。

migrateコマンドでmakemigrationsコマンドで生成された設定ファイルに基づいてテーブルの作成や変更が行われる様子

ウェブアプリを初めて開発する場合、データベース上にテーブルが存在しない状態となっている可能性が高いです。そのため、ウェブアプリでデータベースへのレコードの保存等を行いたいのであれば、まずは上記のような操作を行なってテーブルを作成しておく必要があります。

マイグレーションの実行タイミング

また、上記の操作によってデータベースに作成されるテーブルは、makemigrations コマンドを実行したタイミングにおける models.py に基づいたものになります。したがって、上記の操作を行なった後に models.py を変更すると、データベースに存在するテーブルと models.py に定義したクラスやそのオブジェクトとで持っているフィールドが異なってしまうことになり、この場合はテーブルへのレコードの保存に失敗する可能性があります。

そのため、models.py を変更した場合は(特にクラスのフィールドを追加・削除・変更した場合)、上記の2つのコマンドを実行してテーブルを更新する必要があるので注意してください。

2回目以降に makemigrations コマンドを実行した場合、前回 makemigrations コマンドを実行した時からの models.py の差分に基づいた設定ファイルが migrations フォルダに作成されることになります。

admin.py

自動生成されるファイルとして最後に紹介するのが admin.py となります。この admin.py は管理画面の設定ファイルとなります。

管理画面を示す図

この管理画面は Django フレームワークの持つ admin というアプリによって提供される機能となります。

より具体的には、settings.py で下記のように settings.pyINSTALLED_APPS を変更したと思いますが、下記における django.contrib.admin が管理画面を提供するアプリとなります。そして、プロジェクト内のアプリにおける admin.py は、この admin アプリのセットアップ時に読み込まれる設定ファイルであり、admin.py の設定に基づいて admin アプリが動作するようになります。

settings.pyでのINSTALLED_APPSの設定
INSTALLED_APPS = [
    'testapp', # 'testapp.apps.testapp'でも可
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

この管理画面ではデータベースのテーブルへの操作を行うことができます。具体的には、テーブルに対してレコードの追加・変更・削除等を行うことができます。例えばアプリのユーザーの情報もレコードとしてテーブルに保存されているため、ユーザーの追加や削除なども管理画面から行うことが可能です。

ただし、models.py に定義したクラスはデータベースのテーブルとして扱われるのですが、デフォルトでは models.py に定義したクラスは管理画面での操作対象となっていません。

デフォルトで操作可能なテーブル(クラス)は UserGroups と呼ばれるもののみになります(ちなみに、これらは django.contrib.auth アプリで定義されているモデルとなります)。

デフォルトで管理画面から操作可能なテーブルを示す図

そのため、models.py に定義したクラスに対応するテーブルに対して管理画面から操作を行いたい場合は別途設定が必要であり、その設定を行うのが admin.py となります。

例えば、models.py で紹介した Person クラスであれば、下記のように admin.py を変更することで管理画面から操作可能となります。

Personクラスの管理の設定
from django.contrib import admin
from .models import Person

# Register your models here.
admin.site.register(Person)

前述の通り、この admin.py は Django フレームワークの admin アプリセットアップ時に読み込まれ、admin.py に従って管理画面が表示されるようになります。上記のように変更を行なった場合は、下の図のように Person テーブルへの操作画面へのリンク(Persons)が表示されるようになり、リンク先からレコードの追加等が行えるようになります。

admin.pyの変更により管理画面から操作可能なテーブルが増えたことを示す図

スポンサーリンク

その他の重要なファイル・フォルダ

さて、ここまでは startproject および startapp コマンドによって自動的に生成されるファイルについてのみ解説を行なってきました。

次は、startproject および startapp コマンドによって自動生成はされないものの、別途自身で作成を行なって利用するファイルや後から作成されるファイルの代表的なものを紹介していきたいと思います。

templates

その1つは templates フォルダになると思います。このフォルダはアプリの直下に作成します。さらに、このフォルダの下にアプリ名と同じ名前のフォルダを設置し、さらにそのフォルダの下にテンプレートファイルを設置していくことになります。

templatesフォルダの説明図

このテンプレートファイルは MTV における T (Template) の役割を果たす重要なファイルになります。Django におけるテンプレートとは、簡単に言えば変数を埋め込み可能な HTML の雛形になります。そのファイルがテンプレートファイルで、拡張子としては .html が利用されます。

テンプレートで雛形部分だけを固定して作成しておき、状況に応じて変数部分のみを変化させることで、1つのテンプレートから無数のページ表示を行うことができるようになります。

例えば templates/アプリ名 フォルダの中に下記のような index.html を用意しておけば、{{username}}{{age}}{{height}}{{weight}} の部分は変数のように扱われ、この部分にページ表示時の状況に応じたデータを埋め込むことができるようになります。

テンプレートファイルの例
<!DOCTYPE html>
<html lang="'ja">
    <head>
        <meta charset="utf-8">
        <title>index.html</title>
    </head>
    <body>
        <h1>index.html</h1>
        <div>
            <h2>{{username}}の情報</h2>
            <p>年齢:{{age}}</p>
            <p>身長:{{height}}</p>
            <p>体重:{{weight}}</p>
        </div>
    </body>
</html>

このテンプレートへのデータの埋め込みを実現する関数が、Django フレームワークから提供される render 関数になります。

この render 関数では、第2引数で指定されたテンプレートファイルに対し、第3引数で指定された辞書データの各キーに対する値を、そのキーに対応するテンプレートファイルの変数部分に埋め込む処理が行われます。

render関数の説明図

さらに、この render 関数は、埋め込み後の HTML をレスポンスのボディ部とする HttpResponse のオブジェクトを返却します。

例えば下記のように views.pyindex 関数を作成しておけば、引数で指定された person_id の値を id フィールドに持つレコードがデータベースから取得され、さらに、そのレコードの usernameageheightweight フィールドの値をセットした辞書データ contextrender 関数の第2引数に指定されることになります。

render関数の利用例
from django.shortcuts import render
from .models import Person

def index(request, person_id):
    person = Person.objects.get(id=person_id)
    
    context = {
        'username' : person.username,
        'age' : person.age,
        'height' : person.height,
        'weight' : person.weight,
    }

    return render(request, 'testapp/index.html', context)

これにより、context における各キーの値が、前述で紹介した index.html における {{キー}} の部分に埋め込まれ、その結果をボディとした HttpResponse のオブジェクトが index 関数から返却されることになります。つまり、上記の index 関数はリクエスト受け取って HttpResponse のオブジェクトを返却する構造となっており、ウェブアプリとして必要な処理を行う関数となっています。

views.pyにおける典型的な処理の流れを示す図

前述で紹介した index 関数のように、データベースからデータを取得し、さらにそのデータをテンプレートファイルに埋め込み、その結果を HttpResponse として返却する構造は、MTV それぞれが連携して動作する典型的な例であり、views.py で定義する関数の基本的な形になるので覚えておくと良いと思います。

また、今回は説明しませんが、テンプレートでは「テンプレートタグ」を利用することで条件分岐や繰り返し処理などを行ってテンプレートへの値の埋め込みを行うこともできます。これらのテンプレートの詳細については今後の連載である下記ページで解説していますので、詳細に関しては下記ページを参照していただければと思います。

Djangoのテンプレートの解説ページアイキャッチ 【Django入門4】テンプレートの基本

forms.py

ここまで、主にウェブアプリでページの表示を行う場合の動作について説明を行なってきました。

ただ、あなたが使用したことのあるウェブアプリを思い出しても分かるように、ウェブアプリではページが表示されるだけでなく、ユーザーがデータを入力し、それをウェブアプリに送信できるようになっているものが多いです。

例えば Twitter では、ユーザー登録を行う際にユーザーの情報を入力してウェブアプリに送信しますし、ツイートに関してもユーザーがツイートしたい内容を入力してウェブアプリに送信することで行われることになります。そして、こういった送信したデータはデータベースに保存され、後でページ表示時等に取得される形で利用されるようになっています。

ユーザーからのデータ送信を受け付け、送信された〜データをデータベースに保存する様子

こういったデータの入力をユーザーから受け付けるために利用するのが forms.py であり、この forms.py ではフォームの定義を行います。

例えば下の図のようなフォームをページに表示すれば、ユーザーから名前・年齢・身長・体重を入力してもらうことができ、さらに送信ボタンを押してもらうことでウェブアプリに入力されたデータが送信されるようになります。

入力フォームの例を示す図

上の図のようなフォームは forms.py に下記のような Form のサブクラスを定義することで実現することができます。

Formの定義例
from django import forms

class PersonForm(forms.Form):
    username = forms.CharField(label='名前', max_length=20)
    age = forms.IntegerField(label='年齢')
    height = forms.FloatField(label='身長')
    weight = forms.FloatField(label='体重')

このフォームで入力可能なデータは models.py で紹介した Person クラスの各フィールドに対応しているため、このフォームから送信された各データを Person オブジェクトの各フィールドの設定してデータベースに保存するようにすれば、ユーザーから入力された情報に基づいたレコードの保存を行うことができるようになります。

もちろん、フォームでツイートなどを送信できるようにすれば、ツイートをデータベースに保存し、それを後から取得してページに表示するようなことも可能になります(ただし、ツイートを保存するためのクラスを models.py に定義しておく必要があります)。

このように、ユーザーからのデータの送信を受け付けたいときに、forms.py が活躍することになります。

ただ、こういったフォームを表示するためには、HTML に上記のような forms.py で定義したクラスのインスタンスを埋め込むようなことが必要になりますし、データが送信されてきた際に、そのデータに対する処理、例えばデータベースにレコードとして保存するような処理も必要となります。

この辺りは、今後の連載の中で解説を行なっていきますので、まずは、Django においてもユーザーからのデータの入力や送信を受け付けることが可能であり、それを実現するためのファイルが forms.py であると覚えておくと良いと思います。

アプリの urls.py

別途作成する機会の多いファイルの1つに urls.py があります。

もう忘れてしまった方もおられるかもしれませんが、実は前述の urls.pyurls.py の紹介を行なっています。ただし、それはプロジェクト設定内の urls.py であり、今回紹介するのはアプリ内の urls.py になります(このファイルは自動生成されないため、自身で新規作成する必要があります)。

ここで説明を行うurls.pyがアプリ内のものであることを示す図

前述の通り、プロジェクト設定内の urls.py は Django フレームワークから読み込まれ、Django フレームワークがリクエストを受け取った際に、この urls.py での設定に基づいてプロジェクト内(アプリ内)の関数やメソッドの実行が行われることになります。

この urls.py はアプリ内にも用意することができ、プロジェクト設定フォルダ内の urls.py が読み込まれた際に、アプリ内の urls.py も読み込まれるようにすることができます。

これにより、URL と関数との関連付け設定をアプリごとに別々のファイルで行うことができるようになります。

例えば、プロジェクトに testapp というアプリが存在するとし、さらにプロジェクト設定フォルダ内の urls.py を下記のように作成していたとします。

urls.pyの設定例
from django.contrib import admin
from django.urls import path
from testapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('testapp/', views.index, name='index'),
    path('testapp/signup/', views.signup, name='signup'),
    path('testapp/login/', views.login, name='login'),
]

urlpatterns のリストにおける最初の要素以外は全て、testapp の中のファイルで定義された関数を呼び出すための設定になります。

このような URL と関数との関連付けは、別途 testapp の中に urls.py を下記のように新規作成し、

アプリのurls.py
from django.urls import path
from testapp import views

urlpatterns = [
    path('', views.index, name='index'),
    path('signup/', views.signup, name='signup'),
    path('login/', views.login, name='login'),
]

さらにプロジェクト設定フォルダ内の urls.py を下記のように変更することでも実現することができます。

プロジェクト設定のurls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('testapp/', include('testapp.urls'))
]

この場合、Django フレームワークからはプロジェクト設定の urls.py が読み込まれますが、上記のように include を行うようにしておけば、プロジェクト設定の urls.py が読み込まれる際に testapp 内の urls.py が読み込まれるようになります。

プロジェクト設定のurls.pyからアプリのurls.pyが読み込まれる様子

最初に紹介した、プロジェクト設定フォルダ内のみに urls.py を用意した場合と、上記のようにプロジェクト設定フォルダ内とアプリ内との両方に urls.py とでは全く同じように Django フレームワークの設定が行われることになります(リクエストを受け取った際に実行する関数が同じになる)。

であれば、わざわざアプリに urls.py を用意する必要もない気もすると思うのですが、プロジェクトとアプリの依存度を減らすために、このようにプロジェクト設定フォルダとアプリの両方に urls.py を用意することが多いです。

特に、ウェブサイト等で公開されている Django で開発されたウェブアプリのソースコードでは、プロジェクト設定とアプリの両方に urls.py を用意していることが多いので、プロジェクト設定の urls.py からアプリの urls.py を読み込ませることができることは覚えておくと良いと思います。

db.sqlite3

ファイルの紹介として最後に扱うファイルが db.sqlite3 になります。このファイルはマイグレーション実行時等に自動的に作成されます。作成される位置はプロジェクト設定・アプリ・manage.py と同じ階層になります。

この db.sqlite3 はデータベースそのものになります。マイグレーションを実行すれば、このファイル内にテーブルが作成されることになります。またレコード保存を行えば、このファイル内にレコードの情報が保存されることになります。

ただし、このファイルが作られるのは settings.py の設定によって Django フレームワークが使用するデータベースが「SQLite3」に設定されている場合のみであり、他のデータベースが使用されるように設定されている場合は作成されません。

また、db.sqlite3 はバイナリファイルであり、テキストエディターなどで開いても中身(存在するテーブルやレコード)が確認しにくいので注意してください。

例えば、VSCode を利用して開発しているのであれば、下記ページで紹介している VSCode のプラグインを利用して db.sqlite3 に存在するテーブルやレコードを表形式で表示して確認することができるようになります。

VSCodeでデータベースのテーブルの中身を表示する方法の解説ページアイキャッチ 【Django/VSCode】データベースのテーブルの中身を表示する

意図したテーブル作成やレコード保存が行われているかを表形式で簡単に確認できるようになるため、データベースの中身が気になる場合は、こういったプラグイン等を利用することも検討してみると良いと思います。

Django のウェブアプリの動作の仕組み

ここまでプロジェクト内のファイルについて解説を行なってきました。ただ、基本的に各ファイルについて独立に解説してきましたので、次はウェブアプリが動作する際に、プロジェクト内のファイルがどういう風に利用され、さらには、どのように連携して動作するのかについて解説していきたいと思います。

ここでは Django の開発用サーバー で紹介した開発用サーバーを利用する場合の動作について解説していきます。ウェブサーバーや AP サーバーを利用した場合は多少動作が異なるので注意してください。

Django 開発用サーバーの起動

Django 開発用サーバーを利用する場合、ウェブアプリを動作させるために最初に行うのは Django 開発用サーバーの起動となります。

この Django 開発用サーバーの起動は、manage.py で紹介した manage.py を利用したコマンドの実行によって行うことができます。

manage.pyを利用したrunserverコマンドの実行により開発用サーバーが起動する様子

具体的には、manage.py が存在するフォルダ内(プロジェクト直下)で下記コマンドを実行することで Django 開発用サーバーが起動します。

% python manage.py runserver

スポンサーリンク

settings.py の読み込み

Django 開発用サーバーを利用する場合、Django 開発用サーバーを起動した際にウェブアプリのセットアップも行われることになります。

最初に行われるのは settings.py の読み込みになります(読み込みとは、具体的には import のことを言っています)。

settings.py で解説したように、settings.py はウェブアプリにおける Django フレームワーク部分の動作の設定を行うものであり、この読み込みが行われることで、settings.py での設定に基づいて Django フレームワークが動作するようになります。

また、ウェブアプリを動作させるという点でポイントになるのが、settings.py での INSTALLED_APPS の設定になります。この設定により Django フレームワークがアプリの存在を認識し、settings.py の読み込みによって、INSTALLED_APPS に指定されたアプリのセットアップが行われます。

settings.pyの読み込みによりDjangoフレームワークの動作の設定が行なわれ、さらにDjangoフレームワークがインストールされているアプリを認識する

アプリのセットアップ

続いて、このアプリのセットアップの流れを説明していきます。

下記の流れはプロジェクト内に存在するアプリだけでなく、settings.pyINSTALLED_APPS に指定されている全アプリに対して行われるものになります。

apps.py の読み込み

アプリのセットアップにおいて、まず行われるのが apps.py の読み込みになります。これにより、アプリに設定された情報(例えば名前など)を Django フレームワークが認識することになります。

apps.pyの読み込みによってDjangoフレームワークがアプリの設定を認識する様子

models.py の読み込み

続いて、models.py の読み込みが行われます。これにより、アプリで扱うモデルのクラスを Djangoo フレームワークが認識することになります。models.py で解説したように、このモデルのクラスはデータベースにおけるテーブルとして扱われ、さらにモデルのインスタンスはテーブルのレコードとして扱われます。

models.pyの読み込みによってDjangoフレームワークがテーブルの情報を認識する様子

admin.py の読み込み

アプリのセットアップにおいては、最後に ready メソッドが実行されることになります。この ready メソッドは AppConfig というクラスに用意されているメソッドであり、apps.py が自動生成された際に、この AppConfig のサブクラスが apps.py に自動的に定義されることになります。

例えば下記は testapp というアプリの apps.py の例になり、AppConfig のサブクラスとして TestappConfig クラスが定義されているのが確認できると思います。

apps.pyの例
from django.apps import AppConfig


class TestappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'testapp'

この AppConfig のサブクラスで ready メソッドを定義してやれば、そのメソッドがアプリのセットアップの最後に実行されることになります。ready メソッドを定義しなかった場合は、AppConfigready メソッドが実行されることになり、この場合は何も行われません。

例えば下記のように ready メソッドを定義すれば、アプリのセットアップの最後に標準出力に Finish set-up という文字列が出力されるようになります。

readyメソッドの例
from django.apps import AppConfig


class TestappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'testapp'

    def ready(self):
        print('Finish set-up')

ここでポイントになるのが、まず apps.py で ready メソッドを定義することにより、アプリのセットアップの最後に所望の処理を行わせるようにすることができるという点になります。

もう1つのポイントが、Django フレームワークにおける admin アプリでは、ready メソッド実行時に INSTALLED_APPS に指定されている全アプリの admin.py が読み込まれるようになっているという点になります。

前述の通り、ここで説明しているアプリのセットアップは INSTALLED_APPS に指定された全アプリに対して実行されることになります。さらに INSTALLED_APPS には admin(django.contrib.admin) が指定されているため、admin のセットアップの最後で admin における ready メソッドが実行され、その中でプロジェクトのアプリ内の admin.py が読み込まれることになります(INSTALLED_APPS に指定されている他のアプリの admin.py も読み込まれる)。

そして、この読み込みによって、admin.py の設定に従った管理画面を admin アプリが提供してくれるようになっています。より具体的には、admin.py で登録されたモデルに対応するテーブルを管理画面から操作できるようになります。

admin.pyの読み込みによってDjangoフレームワークの管理画面機能が管理対象のテーブルを認識する様子

以上が、INSTALLED_APPS に指定されている各アプリに対して実行されるセットアップ処理になります。

これらの一連のセットアップ処理は、あくまでも settings.pyINSTALLED_APPS に指定されているアプリに対して実行されるという点に注意してください。INSTALLED_APPS に自身が開発したアプリを指定しなかった場合、当然セットアップは実施されず、アプリのセットアップの後に実行される処理で例外が発生する可能性があります。

特に Django を使い始めて間もない頃は、INSTALLED_APPS へのアプリの指定を忘れがちなので注意してください。

urls.py の読み込み

以上でアプリのセットアップは完了で、開発用サーバーを利用する場合は、続いて開発用サーバーの起動が続行されることになります。そして、この中でプロジェクトのチェックが行われることになります。プロジェクトの settings.py での設定やプロジェクト内のファイルに文法的な間違いなどがある場合は、このチェック時に例外が発生することになります。

このプロジェクトのチェックが行われる際、Django フレームワークから urls.py が読み込まれることになり、この読み込みによって、Django フレームワークがリクエストを受け取った際に、リクエストされた URL に応じて実行する関数を振り分けることができるようになります。

urls.pyの読み込みによってDjangoフレームワークが各URLに対するリクエストを受け取った際に実行する関数・メソッドを認識する様子

このときに読みこまれる urls.py はプロジェクト設定フォルダ内のものになりますが、その urls.py の中でアプリ内の urls.pyinclude するようにしている場合、プロジェクト設定フォルダ内の urls.py を読み込む際に、アプリ内の urls.py も読み込まれることになります。

スポンサーリンク

wsgi.py の読み込み

ここまでの動作により、ウェブアプリのセットアップと開発用サーバーの起動が行われていくことになります。

ただし、ウェブアプリのセットアップと開発用サーバーの起動は独立して行われていくことになるため、開発用サーバーはウェブアプリの実行方法を知りません。

この実行方法を知るために、続いて開発用サーバーから wsgi.py の読み込みが行われます。そして、この wsgi.py の読み込みによって、開発用サーバーがウェブアプリを動作させるときに実行するオブジェクトを取得することになります。

このオブジェクトは、具体的には Django フレームワークで定義される WSGIHandler というクラスのオブジェクトになります。このクラスには __call__ と呼ばれるメソッドが用意されており、WSGIHandler のオブジェクトは呼び出し可能なオブジェクトとなります。そして、WSGIHandler のオブジェクトを呼び出した際にはウェブアプリの Django フレームワークが動作するようになっています。

wsgi.pyの読み込みによって開発用サーバーがウェブアプリを動作させるためのオブジェクトを取得する様子

さらに、オブジェクトの呼び出し時には引数としてリクエストが指定できるようになっています。したがって、開発用サーバーがウェブブラウザ等から受け取ったリクエストは Django フレームワークに渡されることになり、Django フレームワークは受け取ったリクエストの URL に応じて関数やメソッドを実行します。

このときに実行される関数は urls.py によって決定されますが、基本的には実行される関数は views.py に定義される関数(View の役割を果たす関数)となり、この関数からはレスポンスが返却されることになります。

そして、このレスポンスが開発用サーバーに返却され、あとは開発用サーバーがウェブブラウザにレスポンスを返却することで、ウェブブラウザにページ表示が行われることになります。

このレスポンスを返却する処理はコールバックと呼ばれる仕組みを利用して実現されているのですが、この辺りの詳細の解説は省略させていただきます。

以上の動作の流れによって、開発用サーバーを介してウェブアプリがリクエストを受け取り、そのリクエストに応じた処理を実行してレスポンスを返却するという流れが実現されることになります。

ウェブアプリが動作する際に呼び出しされる関数やメソッド等がwsgi.pyとurls.pによって決まることを示す図

アプリの実行

ここまで説明してきた流れの処理が行われることで、開発用サーバーの起動・ウェブアプリ(Django フレームワークやアプリ)のセットアップが完了することになります。これらが完了すればウェブアプリが動作可能となり、開発用サーバーはウェブブラウザ等のクライアントからのリクエスト待ちの状態になります。

そして、リクエストを受け取った際には、前述の通り、開発用サーバーから WSGIHandler オブジェクトを利用して Django フレームワークが実行され、この Django フレームワークからは urls.py の設定に基づいて views.py の関数やメソッドが実行されることになります。

この views.py の関数やメソッドでの最低限の役割は HttpResponse のオブジェクトを返却すること(もしくは例外を発生させること)になるのですが、この HttpResponse におけるボディを生成するために moldes.py で定義されたクラスやメソッドを利用してデータベースからデータを取得したり、templates 内のテンプレートファイルに取得したレコードの情報を埋め込んだりする処理も行われることになります。

また、クライアントからデータが送信されてきた際には、そのデータをレコードとしてデータベースに保存するような処理も行われます。

要は、Django フレームワークから実行されるのは views.py で定義された関数やメソッド(View)になるのですが、この関数やメソッドから moldes.py で定義されたクラスやそのメソッド(Model)、さらには templates 内のテンプレートファイル(Template)が利用されることになります(Form を利用する場合もあります)。

つまり、Django における MTV モデルにおける Model・Template・View が連携して動作することでレスポンス(HttpResponse)の返却が行われます。

プロジェクト内のMTVが動作してレスポンスが返却される様子

また、プロジェクトの特に View や Model は Django フレームワークから提供される機能を利用して動作することになります。例えば Template に Model のフィールドの値を埋め込むために render 関数が利用されますし、Model のインスタンスに save メソッド等を実行させた際には、Django フレームワークから提供される DB 操作の機能が利用されることになります。

そして、この際には Django フレームワークは settings.py の設定に従って動作することになります。

プロジェクトからDjangoフレームワークの機能が利用される様子

このように、Django で開発したウェブアプリでは Model・Template・View、さらには Django フレームワークが連携することで動作することになります。

開発用サーバーを利用しない場合の動作の流れ

最後に1点補足しておくと、前述の通り、ここまで説明してきた動作の流れは、あくまでも開発用サーバーを利用したときのものになります。つまり、開発用サーバーを利用しないウェブアプリ公開時等は動作の流れが異なることになります。

例えば AP サーバーとして uWSGI というソフトウェアを利用する場合、uWSGI から最初に読み込まれるのはwsgi.py となります。そして、AP サーバーが wsgi.py を読み込む際に settings.py の読み込みやウェブアプリのセットアップが行われることになりますし、ウェブアプリを実行させるときに呼び出す WSGIHandler クラスのオブジェクトの取得も行われることになります。

ただし、開発用サーバーは起動時にプロジェクトのチェックを行いますが、uWSGI ではプロジェクトのチェックが行われません。そのため、uWSGI を利用する際には、プロジェクトのチェック時に urls.py が読み込まれるのではなく、最初にウェブアプリが実行されたときに urls.py の読み込みを行うようになっています。

ちなみに、開発用サーバーではプロジェクトのチェックをスキップすることができるようになっています。具体的には、開発用サーバー起動時のコマンドに引数を --skip-checks を指定することで、プロジェクトのチェックがスキップされるようになります。

% python manage.py runserver --skip-checks

この場合は、uWSGI を利用する場合と同様に、最初にウェブアプリがサーバーから実行されたときに urls.py の読み込みが行われるようになります。

ここまでの説明のように、開発用サーバーを利用する場合と、AP サーバーを利用する場合とではウェブアプリの動作の流れ(順番)が若干異なることになります。ですが、どちらの場合もプロジェクト内に用意するファイルの役割は基本的には同じですので、まずは各ファイルの役割をしっかり理解しておくことが重要になると思います。

スポンサーリンク

まとめ

このページでは、Django の全体像と Django の動作の仕組みについて解説しました!

Django で開発するウェブアプリは、大きく分けて Django フレームワークとプロジェクトの2つから構成されます。さらにプロジェクトはプロジェクト設定と1つ or 複数のアプリから構成されます。

プロジェクト設定は主に Django フレームワークの動作を設定するものであり、アプリはウェブアプリの独自の機能や動作を実現していくためのものであると考えると、これらの関係性がわかりやすくなると思います。

最初にも説明したように、Django を利用するデメリットは「慣れるまでが大変」である点だと私は考えています。このページで解説した Django の全体像や Django のウェブアプリの動作の仕組みを覚えておくだけでも Django に慣れやすくなると思いますので、是非このページで解説したことは頭の中に入れておいてください!

また、ここまでは Django の全体像を理解していただくことを目的に解説を行なってきましたが、次の連載からはウェブアプリを開発するために必要となる知識としてビューやテンプレート、モデル等の具体的な解説を行なっていきます。まずは、次の連載となる下記ページでビューについて解説を行なっていますので、是非下記ページも読んでみてください!

Djangoのビューについての解説ページアイキャッチ 【Django入門3】ビューの基本とURLのマッピング

同じカテゴリのページ一覧を表示