🐍

【Python】Djangoでフォーム作成

2024/06/25に公開

完成イメージ

  • フォームと投稿一覧

    初学者でも簡単に実装できます!

開発環境:

  • windows 11
  • Vscode 1.87.2
  • Docker 26.1.1
  • Docker-compose 2.27.0
  • python

環境構築がまだの方はこちらから↓

https://zenn.dev/code_journey_ys/articles/ddd8ba305a2538

1.フォルダ作成 ~ VScodeの起動

1-1.ディレクトリ(フォルダ)を作成

コマンドプロンプトまたはWindows PowerShellにて実行(デスクトップ上にフォルダを作成)
mkdir test-django-project

1-2.ディレクトリを移動

コマンドプロンプトまたはWindows PowerShellにて実行
cd test-django-project

1-3.VScodeを開く

コマンドプロンプトまたはWindows PowerShellにて実行
cd test-django-project

2.Docker関連ファイルの作成

2-1.Dockerfileを作成する

VScodeのターミナル(powershell)にて実行
New-Item dockerfile

2-2.Dockerfileの記述

Dockerfileへ以下の内容をコピペ
# ベースイメージとして公式のPythonイメージを使用
FROM python:3

# 作業ディレクトリを設定
WORKDIR /app

# 必要なライブラリをインストールするためのrequirements.txtをコピー
COPY requirements.txt .

# ライブラリのインストール
RUN apt-get update && apt-get install -y \
  libpq-dev \
  && pip install --upgrade pip \
  && pip install -r requirements.txt

# プロジェクトファイルをコンテナにコピー
COPY . .

# ポート8000を開放
EXPOSE 8000

# コンテナ起動時に実行するコマンド(Django開発サーバーを起動)
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

2-3.docker-compose.ymlファイルの作成

VScodeのターミナル(powershell)にて実行
New-Item docker-compose.yml

2-4.docker-compose.ymlファイルの記述

docker-compose.ymlへ以下の内容をコピペ
services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    networks:
      - test-django-project-network
    depends_on:
      - db

  db:
    image: postgres:13
    environment:
      POSTGRES_DB: mydatabase
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
    ports:
      - "5432:5432"
    networks:
      - test-django-project-network

networks:
  test-django-project-network:

2-5.requirements.txtファイルの作成

VScodeのターミナル(powershell)にて実行
New-Item requirements.txt

2-6.requirements.txtファイルの記述

以下の内容をコピペ
Django>=3.2,<4.0
psycopg2-binary>=2.9.5


ここまでの完成すると上記画面になる

3.Djangoプロジェクトの作成と初期設定

3-1:Djangoプロジェクトの作成

docker-compose run web django-admin startproject test_django_project .
実行結果
実行結果
$ docker-compose run web django-admin startproject test_django_project .
[+] Running 1/1
 ✔ Container test-django-project-db-1  Started                                                                                                                           1.0s 
[+] Building 53.7s (10/10) FINISHED                                                                                                                            docker:default
 => [web internal] load build definition from dockerfile                                                                                                                 0.1s
 => => transferring dockerfile: 734B                                                                                                                                     0.0s 
 => [web internal] load metadata for docker.io/library/python:3                                                                                                          0.0s 
 => [web internal] load .dockerignore                                                                                                                                    0.0s
 => => transferring context: 2B                                                                                                                                          0.0s 
 => [web 1/5] FROM docker.io/library/python:3                                                                                                                            0.0s
 => [web internal] load build context                                                                                                                                    0.1s 
 => => transferring context: 1.38kB                                                                                                                                      0.1s 
 => CACHED [web 2/5] WORKDIR /app                                                                                                                                        0.0s 
 => [web 3/5] COPY requirements.txt .                                                                                                                                    0.2s
 => [web 4/5] RUN apt-get update && apt-get install -y   libpq-dev   && pip install --upgrade pip   && pip install -r requirements.txt                                  51.0s
 => [web 5/5] COPY . .                                                                                                                                                   0.1s
 => [web] exporting to image                                                                                                                                             2.0s
 => => exporting layers                                                                                                                                                  1.8s
 => => writing image sha256:3d91dd03f784c76447806be481f4fe246f0a36c4a6190382c1a31022b04ac5ed                                                                             0.0s
 => => naming to docker.io/library/test-django-project-web                                                                                                               0.0s

3-2:Djangoプロジェクトの作成の確認


test_django_projectフォルダが作成されている確認する

3-3:Djangoプロジェクトのデータベース設定

test_django_project/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'myuser',
        'PASSWORD': 'mypassword',
        'HOST': 'db',
        'PORT': '5432',
    }
}

3-4:Djangoアプリケーションの作成

docker-compose run web python manage.py startapp person

3-5:Djangoアプリケーションの作成の確認


personアプリケーションとtest_django_projectプロジェクトが作成されているか確認

Djangoプロジェクトとアプリケーションの違い
  • Djangoプロジェクト:
    ・全体の設定、ルーティング、および複数のアプリケーションを含むコンテナ。
    ・プロジェクトには、サイト全体に影響を与える設定ファイルが含まれます。

  • Djangoアプリケーション:
    ・具体的な機能を提供するモジュール。
    ・独立した機能セット(例:ユーザー認証、ブログ、ニュースフィードなど)を実装する。

3-6:Djangoアプリケーションの設定

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'person',
]
INSTALLED_APPSにプロジェクト名を追加する理由
  • モデルの認識:
    INSTALLED_APPSに追加することで、そのアプリケーション内で定義されたモデルがDjangoによって認識され、データベースのマイグレーションが可能になります。例えば、test_django_projectというアプリケーションにモデルを定義している場合、そのモデルがデータベースに反映されるようにマイグレーションを行うには、そのアプリケーションがINSTALLED_APPSにリストされている必要があります。

  • 管理画面への反映:
    アプリケーションがINSTALLED_APPSにリストされることで、Djangoの管理画面からそのアプリケーションのモデルを管理することができます。これにより、管理者はデータの追加、編集、削除などを容易に行えます。

  • アプリケーションの設定:
    INSTALLED_APPSに追加することで、そのアプリケーションに関連する設定が適用されます。例えば、テンプレートディレクトリ、静的ファイルディレクトリ、シグナルなどが正しく設定されます。

4.コンテナ起動~ページ表示確認

4-1:Dockerコンテナを起動する

ターミナル
docker-compose up --build

4-2:ブラウザからhttp://localhost:8000/にアクセスし、トップページが表示されるかを確認する

5.モデルの作成とマイグレーション

5-1:models.pyファイルの編集

person/models.py(中身をコピペして入れ替える)
from django.db import models

# Create your models here.
class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)
    email = models.EmailField()
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

5-2:マイグレーション実行の準備

docker-compose run web python manage.py makemigrations

5-3:マイグレーションの実行

docker-compose run web python manage.py migrate
マイグレーションの出力結果
出力結果
$ docker-compose run web python manage.py makemigrations
[+] Creating 1/0
 ✔ Container test-django-project-db-1  Running                                                                                             0.0s 
No changes detected

$ docker-compose run web python manage.py migrate
[+] Creating 1/0
 ✔ Container test-django-project-db-1  Running                                                                                             0.0s 
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
2つのマイグレーションコマンドの違い
  • docker-compose run web python manage.py makemigrations:
    このコマンドは、Django モデルの変更を識別し、その変更を反映する移行ファイルを生成するために使用されます。モデルをスキャンし、データベースの現在の状態と比較します。不一致が検出されると、データベースとモデルを同期するために必要な変更の概要を示す新しい移行ファイルが作成されます。

  • docker-compose run web python manage.py migrate:
    このコマンドは、生成された移行ファイルをデータベースに適用し、Django モデルの現在の状態に合わせてデータベース スキーマを効果的に更新するために使用されます。このコマンドは、によって作成された移行ファイルを取得しmakemigrations、データベース テーブルに必要な変更を適用します。

6.フォーム(forms.py)の作成

6-1:forms.pyファイルの作成

アプリケーション内のフォームがforms.pyに集約される
New-Item person/forms.py

6-2:forms.pyファイルの編集

person/forms.py
from django import forms
from .models import Person

class PersonForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = ['first_name', 'last_name', 'email']

7.ビューとテンプレートの作成

7-1:ビューの作成

person/views.py
from django.shortcuts import render

# Create your views here.
from django.shortcuts import redirect
from .forms import PersonForm
from .models import Person

def person_create_view(request):
    if request.method == 'POST':
        form = PersonForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('person_list')
    else:
        form = PersonForm()
    return render(request, 'person_form.html', {'form': form})

def person_list(request):
    people = Person.objects.all()
    return render(request, 'person_list.html', {'people': people})

7-2:テンプレートフォルダの作成

docker-composeのターミナル以外のターミナルから実行
mkdir person/templates


personフォルダの配下にtemplatesフォルダが作成されていることを確認する

7-3:ベーステンプレート(base.html)ファイルの作成

ターミナル
New-Item person/templates/base.html

7-4:base.htmlファイルの記述

person/templates/base.html
<!DOCTYPE html>
<html>
<head>
    <title>{% block title %}My Django App{% endblock %}</title>
</head>
<body>
    <header>
        <h1>My Django App</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'person_create' %}">Create Person</a></li>
            <li><a href="{% url 'person_list' %}">Person List</a></li>
        </ul>
    </nav>
    <main>
        {% block content %}
        {% endblock %}
    </main>
</body>
</html>

7-5:フォームテンプレート(person_form.html)ファイルの作成

ターミナル
New-Item person/templates/person_form.html

7-6:person_form.htmlファイルの記述

person/templates/person_form.html
{% extends 'base.html' %}

{% block content %}
<h1>Person Form</h1>
  <form method="post">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">Submit</button>
  </form>
{% endblock %}

7-7:リストテンプレート(person_list.html)ファイルの作成

ターミナル
New-Item person/templates/person_list.html

7-8:person_list.htmlファイルの記述

person/templates/person_list.html
{% extends 'base.html' %}

{% block content %}
  <h1>Person List</h1>
  <table>
    <thead>
      <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Email</th>
      </tr>
    </thead>
    <tbody>
      {% for person in people %}
        <tr>
          <td>{{ person.first_name }}</td>
          <td>{{ person.last_name }}</td>
          <td>{{ person.email }}</td>
        </tr>
      {% endfor %}
    </tbody>
  </table>
{% endblock %}

8.urls.pyの編集

8-1:アプリケーション側のurls.pyファイルの作成

ターミナル
New-Item person/urls.py

8-2:アプリケーション側のurls.pyファイルの編集

person/urls.py
from django.urls import path

from .views import person_create_view, person_list
urlpatterns = [
    path('create/', person_create_view, name='person_create'),
    path('list/', person_list, name='person_list'),
]

8-3:プロジェクト側のurls.pyの編集

test_django_project/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('person.urls')),  // 追加
    path('person/', include('person.urls')), // 追加
]
それぞれのurls.pyフォルダの意味合い
  • アプリケーション側のurls.py:
    個々のアプリケーションに特化したURLパターンを定義します。モデル、ビュー、テンプレートなど、そのアプリケーションに関連する機能へのアクセスを制御します。プロジェクトレベルの urls.py ファイルからインクルードされることで、プロジェクト全体の中でアプリケーションのURLを管理できます。

  • プロジェクト側のurls.py:
    プロジェクト全体に関わるURLパターンを定義します。典型的な例としては、管理画面へのアクセスや認証関連のURLなどが含まれます。アプリケーションレベルの urls.py ファイルからのインクルード機能を使用して、個々のアプリケーションのURLパターンを統合します。

9.画面の確認

9-1:http://localhost:8000/person/create/にアクセスし、フォームの確認を行う

9-2:フォームに内容を入力し、「submit」をクリックする

9-3:http://localhost:8000/person/list/にリダイレクトされ、投稿一覧が表示されれば成功

Discussion