Djangoは高水準のPythonフレームワークです。そのシンプルさと効率性で、堅牢なWebアプリケーションを構築することができるため人気があります。

Djangoのアーキテクチャの核にはModel-View-Template(MVT)パターンがあります。モデル、ビュー、テンプレートがどのように相互作用するかを理解することは重要であり、Djangoの全力を発揮するためには不可欠です。

Djangoが完全に新しいものであるか初心者であるかに関わらず、この記事は、これらのコンポーネントがどのように機能し、互いに連携して動的なWebアプリケーションを作成するかを示す包括的なガイドとして役立ちます。

さらに理解しやすくするために、これらのコンポーネントの相互関係をよりよく理解するために、シンプルなアプリケーションを構築します。

すでに興奮しているなら、すぐに始めましょう!

以下では、次の内容について説明します:

前提条件

進めるためには、以下が必要です:

  • ウェブアプリケーションがどのように機能するか、クライアント-サーバーアーキテクチャを含む基本的な理解。

  • Pythonの基本的な知識。

MVTアーキテクチャとは何ですか?

MVTパターンは、DjangoのWebアプリケーションのコードベースとワークフローを整理する手法です。このアーキテクチャを構成するコンポーネントは、モデル、ビュー、テンプレートです。各コンポーネントは特定の機能を実行し、その後、他のコンポーネントに処理を渡します。

それぞれの機能を持つコンポーネントを簡単に見てみましょう。

  • モデル:データレイヤーとしても知られており、データを管理しデータベースとやり取りします。

  • ビュー:ロジックレイヤーとしても知られ、仲介者として機能し、ロジックを処理しデータフローを管理します。

  • テンプレート:プレゼンテーションレイヤーとしても知られ、ユーザーインターフェースにHTMLコンテンツをレンダリングします。

これで、Djangoアプリケーションにおけるコンポーネントとその役割についての概念がわかりましたので、各コンポーネントとアーキテクチャ内での相互作用について詳しく見ていきます。

モデルコンポーネント

モデルは、Djangoアプリケーション内のデータの構造と相互作用を管理し、データが果たす重要な役割のため、Djangoアプリの基礎となります。

Djangoモデルは、リレーショナルデータベースとPythonコードの間のギャップを埋める強力な機能であるObject-Relational Mapping (ORM)を利用しています。これにより、Pythonオブジェクト(クラス)がデータベーステーブルに、その属性が列に、インスタンスがそれらのテーブル内の行に変換されます。

ORMの大きな利点の1つは、SQLクエリを書かずにPythonオブジェクトを使用してデータベースとやり取りできることです。観客が理解できるように、1つの言語を別の言語に変換する通訳と考えてください。この場合、ORMはPythonコードをデータベースが実行できるSQLコマンドに変換し、その逆も行います。

Djangoモデルはすべてのデータベース関連のロジックをカプセル化し、データベースの構造を定義して、保存したいデータの設計図として機能します。

Djangoモデルの一般的なフォーマット

Djangoでは、すべてのモデルが特定の宣言方法に従います。以下はモデル宣言の基本構造です:

class <model_name>(models.Model):
    <field_name> = models.<field_type>(<optional_field_characteristics>)

それを分解してみましょう:

  • class: Djangoでモデルを定義するために使用されるキーワード。

  • model_name: モデルの名前。

  • models.Model: モデルクラスが継承する基本クラス。

  • field_name: データベースのカラム名です。

  • field_type: charFieldBooleanFieldなど、フィールドが保持するデータのタイプを指します。

  • optional_field_characteristics: max_lengthdefaultなど、フィールドの挙動をさらに定義するために使用されます。

モデル例

これまでのモデルに関するすべてを知ったので、タスクリスト用のモデルを構築します。通常、タスクのタイトル、説明、およびタスクが完了したかどうかを示すインジケータが含まれます。

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

このモデルでは:

  • Taskはモデルの名前です。

  • Taskモデルには3つのフィールドがあります:

    • title: 最大長が100文字のテキストを保持するCharField

    • description: 長いテキスト用のTextField

    • completed: デフォルトでFalseTrueまたはFalseの値を格納するBooleanField

ビューコンポーネント

Djangoビューはユーザーのリクエストを処理し、レスポンスを返す責任があります。モデルオブジェクトからデータを収集し、それらに対して論理演算を行い(特定の基準に基づくクエリなど)、そのデータをテンプレートに表示するために渡します。

ビューは、アプリケーションの複雑さと要件に応じて、関数またはクラスベースで記述することができます。

Djangoビューの一般的な形式

以下は、ビューの基本的な構造です:

def <view_name>(request):
    # ビューロジックをここに記述します....
    return render(request, <template>, <context>)

詳細を見ていきましょう:

  • view_name:ビュー関数の名前。

  • request:Djangoサーバーにクライアントから送信されるHTTPリクエストで、フォームの送信やボタンのクリックからトリガーされる可能性があります。

  • return render:HTMLレスポンスを生成するために使用されます。以下を受け取ります:

    • request:受信リクエストに関する情報を含むリクエストオブジェクト。

    • template:レンダリングするテンプレートファイル。

    • context:テンプレートで利用可能にする変数を含み、通常は辞書形式で提供されます。

ビューの例

タスクリストを引き続き進めると、ビューは次のようになります:

def task_list(request):
    # ロジックはここに記述...
    return render(request, <template>, {'tasks': tasks})

テンプレートコンポーネント

Djangoテンプレートは、ブラウザ上で最終的なHTML出力をレンダリングする責任があります。これらは、HTMLとDjangoのテンプレート言語の組み合わせを使用してデータの表示方法を定義します。

Djangoのテンプレート言語では、テンプレートタグ {% %}テンプレート変数 {{ }} を使用して、HTMLテンプレート内でDjangoモードに入ることができます。このモードでは、ビューで定義された変数にアクセスして、テンプレート内で制御構造を使用することができます。

テンプレートは、ユーザーインターフェースをより見栄え良くするために、CSSまたはお気に入りのCSSフレームワークを使用してスタイル付けすることもできます。

テンプレートの例

私たちのテンプレートは、Djangoのテンプレート言語を使用した通常のHTMLファイルです。以下は、タスクリストテンプレートの見た目です:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>
</body>
</html>

このテンプレートでは:

  • forループは、tasksリスト内の各タスクを反復処理します(ビューでコンテキストとして渡されたことを覚えています)。

  • 各タスクについて、タスクのtitleとそのcompletedステータス(”Done”または”Not Done”のいずれか)を出力します。

  • tasksリストが空の場合、{% empty %}ブロックには「タスクは利用できません。」という代替メッセージが表示されます。

MVTワークフローを示す図

この図は、DjangoのMVTアーキテクチャ内でデータがどのようにフローするかを示しています。

MVTの現実世界のアナロジー

レストランに行ってお気に入りの料理を注文すると想像してください。舞台裏では、レストランには各料理の調理方法が記載されたレシピ本があります。シェフはレシピを使用して、あなたが注文した通りに料理を用意します。準備ができたら、ウェイターが見栄えの良い状態で料理をお客様に提供します。

シェフが料理を作るためにレシピに従うように、ビューはモデルを使用してデータを収集し処理します。最後に、料理が提供されるように、テンプレートは最終的な出力をユーザーにわかりやすく魅力的な形式で提示します。

プロジェクト全体をまとめる

このセクションでは、記事で例として使用したタスクリストの設定方法を、開始から終了まで案内します。最後には、MVTアーキテクチャが完全に機能しているアプリケーションを持つことができるでしょう。

Pythonのインストール

まず、Pythonがインストールされていることを確認してください。最新のPythonバージョンをダウンロードするには、Pythonの公式ウェブサイトにアクセスしてください。

Djangoプロジェクトとアプリの設定

次に、Djangoをインストールします。pipを使用してインストールできます:

pip install django

フォルダーを作成し、お気に入りのコードエディタで開きます。

ターミナルで次のコマンドを一つずつ実行して、新しいDjangoプロジェクトとアプリを作成します:

django-admin startproject myproject 
cd myproject
django-admin startapp myapp

モデルの定義

あなたのmyapp/models.pyで:

from django.db import models

class Task(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    completed = models.BooleanField(default=False)

フォームの作成

タスクモデルに基づくDjangoフォームが必要ですので、DjangoのModelFormを使用して作成します。

あなたのmyappに、forms.pyという名前のファイルを作成し、次のコードを挿入します:

from django import forms
from .models import Task

class TaskForm(forms.ModelForm):
    class Meta:
        model = Task
        fields = ['title', 'description', 'completed']

このコードでは:

  • Task.modelsからインポートされています。

  • class TaskForm(forms.ModelForm):これは、TaskFormという新しいクラスを作成し、forms.ModelFormのサブクラスです。

  • class Meta:: DjangoのModelFormで使用される特別なクラスで、フォームの構成を提供します。 Metaクラスは関連するモデルとフォームに含めるフィールドを指定することで、Djangoにフォームの作成方法を伝えます。

  • model = Task: フォームが基づいているモデルを指定します。 この場合、フォームはTaskモデルに基づいています。

  • fields = ['title', 'description', 'completed']: Taskモデルからフォームに含めるフィールドを指定します。 これにより、どのモデルフィールドがフォームに表示されるかを制御でき、すべてのフィールドではなく特定のフィールドのみを含めるようにカスタマイズできます。

ビューを作成

myapp/views.pyにこのコードを挿入してください。

from django.shortcuts import render,redirect
from .models import Task
from .forms import TaskForm

def task_list(request):
    tasks = Task.objects.all()    # すべてのタスクを取得

    if request.method == 'POST':    # フォームの送信を処理
        form = TaskForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('task_list')  # 重複した送信を回避するためにリダイレクト
    else:
        form = TaskForm()

    # タスクとフォームをテンプレートに渡す
    return render(request, 'task_list.html', {'tasks': tasks, 'form': form})

このビューでは、

  • TaskFormforms からインポートされています。

  • コードは、リクエストメソッドが POST であるかどうかをチェックし、これはユーザーがフォームを送信したことを示します。

  • メソッドが POST の場合、送信されたデータ(request.POST)を使用して TaskForm のインスタンスを作成します。

  • その後、フォームは form.is_valid() を使用して検証され、有効であれば、フォームはデータベースに保存されます。

  • 保存後、ユーザーは重複提出を防ぐためにタスクリストページにリダイレクトされます。

テンプレートを定義する

あなたの myapp ディレクトリ内に templates フォルダーを作成します。テンプレートフォルダー内にファイルを作成し、名前を task_list.html にします。ユーザーの入力を収集し、UI上のリストに表示するフォーム要素を追加する必要があります。

task_list HTMLファイル内には:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Task List</title>
</head>
<body>
    <h1>Task List</h1>
    <ul>
        {% for task in tasks %}
            <li>{{ task.title }} - {{ task.completed|yesno:"Done,Not Done" }}</li>
        {% empty %}
            <p>No tasks available.</p>
        {% endfor %}
    </ul>

    <h2>Add a New Task</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Add Task</button>
    </form>
</body>
</html>

追加されたフォームコード内には:

  • データ送信のために POST メソッドを使用したHTMLフォームを作成しました。CSRF攻撃から保護するために {% csrf_token %} が含まれています。

  • フォームフィールドは {{ form.as_p }} を使用してレンダリングされ、各フィールドは <p> タグ内に表示されます。

  • 最後に、「タスクを追加」ラベルの付いた送信ボタンが提供され、ユーザーがフォームデータを送信できるようになっています。

フォルダ構造

この時点に達したら、アプリの設定が正しいかどうかを再確認することが重要です。フォルダ/ファイル構造は次のようになります:

└── 📁myproject
    └── 📁myapp
        └── 📁__pycache__
        └── 📁migrations
        └── 📁templates
            └── task_list.html
        └── __init__.py
        └── admin.py
        └── apps.py
        └── forms.py
        └── models.py
        └── tests.py
        └── urls.py
        └── views.py
    └── 📁myproject
        └── 📁__pycache__
        └── __init__.py
        └── asgi.py
        └── settings.py
        └── urls.py
        └── wsgi.py
    └── db.sqlite3
    └── manage.py

プロジェクトのURLを設定する

あなたのmyproject/urls.pyに、myappのURLを含めます:

from django.contrib import admin
from django.urls import path, include

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

アプリをプロジェクト設定に追加する

myappインストールされたアプリのリストにmyproject/settings.pyで追加します:

INSTALLED_APPS = [
    'myapp',      # myappアプリを追加しました
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

サーバーを実行する

マイグレーションを適用し、次のコマンドを入力してサーバーを実行します:

python manage.py migrate

python manage.py runserver

ブラウザでhttp://127.0.0.1:8000/にアクセスしてアプリをテストします。

最終的な外観

タスクをいくつかフォームを使用して追加した後、ブラウザでタスクリストアプリの外観は次のようになります。テンプレートのスタイリングをさらに改善することができます。

結論

この記事では、DjangoのMVTアーキテクチャのコンポーネント、相互作用の仕方、そしてウェブ体験をシームレスにする方法について学びました。また、実際にどのように機能するかを見るためにシンプルなプロジェクトを構築し、今ではより良く理解できていることを願っています。

この記事がお楽しみいただけたら、Xで私をフォローするか、プログラミングの記事や投稿をもっと読むためにLinkedInでつながることができます。

次の記事でお会いしましょう!