Djangoを使ったWebアプリの作り方 ②CURD処理編
①初期設定編ではDjangoの基本的な設定をしました。本編では、アプリの基本的な処理である、CURD処理の実装をしていきます。
CURD処理とは、作成(Create)、読み取り( Read)、更新( Update)、削除( Delete)のことを言います。
CRUD(クラッド)は、データを管理する基本的な4つの操作の頭文字を並べたもので、データベースやウェブアプリの管理にとてもよく使われます。これを理解すると、ウェブサイトやアプリがどのようにデータを扱っているかをイメージしやすくなります
以下に、DjangoでのCRUD処理を実装する手順を詳しく説明します。
1. モデルの作成
まず、CRUD操作を行うためのデータモデルを定義します。myapp/models.pyに以下のように記述します。
from django.db import models
class Item(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
'''
# コードの説明
・Itemというモデル(データの構造)を定義。
・nameは、アイテムの名前を保存するためのフィールド(項目)です。
models.CharFieldは文字列(テキスト)を保存するデータ型です。
ここでは、名前の文字数を100文字以内に制限しています。
・descriptionは、アイテムの説明を保存するフィールドです。
models.TextFieldは長いテキストを保存するためのデータ型です。
・created_atは、アイテムが作成された日時を記録するフィールドです。
models.DateTimeFieldは日付と時間を保存できるデータ型です。
auto_now_add=Trueと指定することで、アイテムが作られたときに自動的にその時点の日時が保存されます。
'''
2. マイグレーションの作成と適用
モデルを作成したら、マイグレーションを作成し、データベースに適用します。
python manage.py makemigrations
python manage.py migrate
3. 管理サイトへの登録
作成したモデルをDjangoの管理サイトで管理できるようにするため、myapp/admin.pyに以下を追加します。
from django.contrib import admin
from .models import Item
admin.site.register(Item)
'''
# コードの説明
・admin.site.register()を使って、Itemモデルを管理画面に登録します。
これにより、Djangoの管理画面にログインすると、Itemが表示され、アイテムの追加・編集・削除が簡単にできるようになります。
'''
4. ビューの作成
CRUD操作を実装するためのビューを作成します。myapp/views.pyに以下のように記述します。
from django.shortcuts import render, redirect, get_object_or_404
from .models import Item
from .forms import ItemForm
# 一覧表示
def item_list(request):
items = Item.objects.all()
return render(request, 'myapp/item_list.html', {'items': items})
'''
# コードの説明
・ Item.objects.all() で、データベースからすべてのItemを取得します。
・ render関数でテンプレート'myapp/item_list.html'を呼び出し、取得したデータ(items)をテンプレートに渡して表示します。
'''
# 作成
def item_create(request):
if request.method == 'POST':
form = ItemForm(request.POST)
if form.is_valid():
form.save()
return redirect('item_list')
else:
form = ItemForm()
return render(request, 'myapp/item_form.html', {'form': form})
'''
# コードの説明
・ request.methodでリクエストがPOST(送信されたデータ)であるか確認します。
・ POSTの場合はフォームデータからItemFormを作成し、データが正しいか確認(form.is_valid())した後、データを保存します。
・ 保存後は一覧ページにリダイレクトします。
・ POSTでなければ空のフォームを作成し、item_form.htmlテンプレートに表示します。
'''
# 更新
def item_update(request, pk):
item = get_object_or_404(Item, pk=pk)
if request.method == 'POST':
form = ItemForm(request.POST, instance=item)
if form.is_valid():
form.save()
return redirect('item_list')
else:
form = ItemForm(instance=item)
return render(request, 'myapp/item_form.html', {'form': form})
'''
# コードの説明
・ get_object_or_404で、データベースからpk(プライマリキー)に該当するItemを取得します。
・ POSTリクエストの場合、フォームが送信され、データをitemに上書きする形でフォームを作成します。
・ データが正しければ保存し、一覧ページにリダイレクトします。
・ POSTでなければ既存のItemの内容を反映したフォームを作成し、テンプレートに表示します。
'''
# 削除
def item_delete(request, pk):
item = get_object_or_404(Item, pk=pk)
if request.method == 'POST':
item.delete()
return redirect('item_list')
return render(request, 'myapp/item_confirm_delete.html', {'item': item})
'''
# コードの説明
・ get_object_or_404でデータベースからpkに該当するItemを取得します。
・ POSTリクエストの場合はitem.delete()でデータを削除し、一覧ページにリダイレクトします。
・ POSTでない場合、削除確認ページitem_confirm_delete.htmlを表示し、ユーザーが本当に削除を行うか確認します。
'''
5. フォームの作成
モデルに基づいたフォームを作成します。myapp/forms.pyに以下を追加します。
from django import forms
from .models import Item
class ItemForm(forms.ModelForm):
class Meta:
model = Item
fields = ['name', 'description']
'''
# コードの説明
・ItemFormという新しいフォームクラスを作成しています。
このクラスはforms.ModelFormを継承しているので、DjangoがItemモデルの情報を使って自動でフォームを生成してくれます。
・Metaクラスは、フォームの設定を指定する部分です。
model = Itemにより、このフォームがItemモデルに基づくものであることを示しています。これにより、Itemモデルのデータに対応した入力フィールドが作成されます。
fields = ['name', 'description']では、フォームに含める項目を指定しています。ここでは、name(名前)とdescription(説明)の2つの項目のみがフォームに表示され、入力できるようになります。
'''
6. URLの設定
作成したビューをURLにマッピングします。myapp/urls.pyを新規に作成し、以下のように記述します。
from django.urls import path
from . import views
urlpatterns = [
path('', views.item_list, name='item_list'),
path('item/new/', views.item_create, name='item_create'),
path('item/<int:pk>/edit/', views.item_update, name='item_update'),
path('item/<int:pk>/delete/', views.item_delete, name='item_delete'),
]
'''
# コードの説明
path_1: このパスは、URLの末尾に何もつかない('')ページに対するものです。たとえばhttps://example.com/にアクセスしたときに、item_listというビュー関数が呼ばれます。
name='item_list'で、このURLに名前をつけています。この名前を使って、他のコードからこのURLにリンクを貼ったりできます。
path_2: item/new/というURLで、アイテムの新規作成ページに対応しています。たとえば、https://example.com/item/new/にアクセスすると、item_createビュー関数が実行されます。
name='item_create'は、このURLの名前です。これを使って、テンプレートや他のコードからこのURLにアクセスできます。
path_3: item/<int:pk>/edit/というURLで、特定のアイテムを編集するページに対応しています。
<int:pk>はURLの一部で、アイテムのID(数字)を指定します。
たとえばhttps://example.com/item/3/edit/とすると、IDが3のアイテムを編集できます。
name='item_update'という名前で、このURLを特定しています。
path_4: item/<int:pk>/delete/というURLで、特定のアイテムを削除するページに対応しています。
<int:pk>部分にアイテムのIDが入るため、URLがアイテムごとに異なります。
たとえば、https://example.com/item/3/delete/とすれば、IDが3のアイテムを削除する画面が表示されます。
name='item_delete'で、このURLの名前を定義しています。
'''
次に、プロジェクトのurls.py(mysite/urls.py)にアプリのURLを追加します。
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('myapp.urls')), # << 追加
]
'''
# コードの説明
path_1: admin/というURLにアクセスすると、Djangoの管理画面に接続されます。
たとえば、https://example.com/admin/にアクセスすると管理画面が表示され、データの管理やユーザーの管理ができるようになります。
admin.site.urlsはDjangoが自動で用意しているURL設定で、これを使うだけで管理画面が利用できるようになります。
path_2: include('myapp.urls')は、myappというアプリケーションのURL設定を読み込むことを意味しています。
path('', ...)と書いているので、プロジェクトのルートURL(つまりhttps://example.com/)にアクセスしたときに、myappのURL設定に基づいて処理が進むようになります。
myapp.urlsファイルに、さらに細かいURLパターンが定義されているので、この部分はmyapp内の個別のページ(一覧表示、作成、編集、削除など)に振り分ける役割を担います。
'''
7. テンプレートの作成
CRUD操作に必要なHTMLテンプレートを作成します。myapp/templates/myapp/ディレクトリを作成し、以下のファイルを作成します。
Djangoのテンプレート(HTMLファイル)で、アイテムの一覧を表示するためのものです。Djangoのテンプレート言語({% %}や{{ }}で囲まれた部分)を使って、動的にアイテムのリストを表示し、各アイテムに対して「編集」と「削除」の操作を行えるようにしています。
item_list.html
ここでは、一覧ページを表示します。
<h1>Item List</h1>
<a href="{% url 'item_create' %}">Create New Item</a>
<ul>
{% for item in items %}
<li>
{{ item.name }} - <a href="{% url 'item_update' item.pk %}">Edit</a>
<form action="{% url 'item_delete' item.pk %}" style="display:inline;">
<button type="submit">Delete</button>
</form>
</li>
{% endfor %}
</ul>
'''
# コードの説明
・<h1>Item List</h1>:ページのタイトルを「Item List」として表示しています。
<a href="{% url 'item_create' %}">Create New Item</a>:リンクを作成しています。
リンク先は、item_createという名前で定義されたURLです(このURLは新しいアイテムを作成するページに対応しています)。リンクのテキスト「Create New Item」が表示され、クリックすると新しいアイテムを作成するページに移動します。と切り替えて表示されます)
・<ul>タグでアイテムのリスト全体を作成しています。
{% for item in items %}:Djangoのテンプレートタグで、itemsの中にある各itemを順番に処理しています。
itemsは、ビューから渡されてきたアイテムのリストで、これによりページ上にすべてのアイテムが順に表示されます。
・<li>タグは、各アイテムをリスト形式で表示するためのタグです。
{{ item.name }}は、各アイテムの名前を表示しています。
({{ }}はDjangoテンプレートで変数を表示するためのタグです。)
<a>タグで編集ページへのリンクを作っています。
{% url 'item_update' item.pk %}は、item_updateという名前のURLにアイテムのID(item.pk)を渡してリンクを生成します。
これにより、特定のアイテムを編集するページに飛べるリンクが作成されます。
削除ボタンは<form>タグの中に配置されています。
actionには、item_deleteという名前のURLが指定され、item.pk(アイテムのID)を渡しています。
<button type="submit">Delete</button>は、削除を実行するためのボタンです。
ユーザーがこのボタンを押すと、フォームがitem_deleteのURLに送信され、対象のアイテムが削除される処理が呼ばれます。
style="display:inline;"とすることで、ボタンとリンクが横並びで表示されます。
'''
以下のように表示されます。
item_form.html
ここでは、実際にデータを入力(編集)するページを表示します。
<h1>{% if form.instance.pk %}Edit{% else %}Create{% endif %} Item</h1>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
<a href="{% url 'item_list' %}">Cancel</a>
'''
# コードの説明
ここでは、入力
・<h1>タグ内のコードは、フォームが「新規作成」用か「編集」用かによってタイトルを変更しています。
{% if form.instance.pk %}は条件分岐で、form.instance.pkが存在する場合(つまり、既存アイテムが編集されている場合)は「Edit」と表示され、存在しない場合(新規作成)は「Create」と表示します。
form.instance.pkは、アイテムがデータベースに保存されたことを示す主キー(ID)です。アイテムがすでに存在する場合はIDがあり、新しいアイテムの場合はIDがないため、これで判断しています。
(この部分で画面上部に「Edit Item」または「Create Item」と切り替えて表示されます)
・<form method="post">:フォームの始まりを示しています。
method="post"とすることで、ユーザーが入力したデータがページに送信されます。
{% csrf_token %}:Djangoのセキュリティ対策として、CSRFトークンを生成しています。
これにより、不正なデータ送信を防止します。
Djangoでフォームを使うときは、このタグを忘れずに入れるのが基本です。
{{ form.as_p }}:ビューから渡されてきたformオブジェクトをHTMLとして表示します。
as_pは、フォームの各フィールドを<p>タグで囲んで表示する指定です。
これにより、フォームの入力フィールドが順に表示されます(例えば「名前」「説明」などの入力欄)。
<button type="submit">Save</button>:送信ボタンです。
ユーザーがこのボタンを押すと、フォームに入力されたデータが保存されます。
・<a href="{% url 'item_list' %}">Cancel</a>:キャンセルボタンとして機能するリンクです。
{% url 'item_list' %}は、item_listという名前がついたURLにリンクを貼るテンプレートタグです。
このコードの場合、キャンセルボタンを押すとアイテムの一覧ページに戻ります。
'''
編集(Edit)の表示画面は以下のように表示されます。
item_confirm_delete.html
ここでは、削除確認ページを表示します。削除(delete)ボタンを押した後の確認画面です。
<h1>Delete Item</h1>
<p>Are you sure you want to delete "{{ item.name }}"?</p>
<form method="post">
{% csrf_token %}
<button type="submit">Confirm</button>
</form>
<a href="{% url 'item_list' %}">Cancel</a>
'''
# コードの説明
・<h1>Delete Item</h1>:ページのタイトルとして「Delete Item」(アイテムを削除)と表示しています。
<p>Are you sure you want to delete "{{ item.name }}"?</p>:削除確認のメッセージです。
{{ item.name }}で削除対象のアイテム名が表示されます。
たとえば、アイテム名が「商品A」なら「Are you sure you want to delete "商品A"?」と表示され、ユーザーに削除するアイテムがどれかを明確に示しています。
・<form method="post">:削除を実行するためのフォームを開始しています。
method="post"で、データがページに送信されるように設定しています。
{% csrf_token %}:CSRFトークンを追加するタグで、Djangoのセキュリティ対策として必須です。
これにより不正なリクエストを防ぎます。
<button type="submit">Confirm</button>:削除を実行するボタンです。
ユーザーがこの「Confirm」ボタンを押すと、フォームが送信されてアイテムが削除されます。
・<a href="{% url 'item_list' %}">Cancel</a>:キャンセルボタンとして機能するリンクです。
{% url 'item_list' %}は、アイテム一覧ページへのリンクを生成します。
この「Cancel」リンクをクリックすると、削除を中止して一覧ページに戻ります。
'''
削除確認画面は以下のように表示されます。
8. フォルダ構成
上記設定後のフォルダ構成は以下となります。
├── ./
├── manage.py # Django管理コマンド
├── db.sqlite3 # SQLiteデータベースファイル
├── Pipfile # プロジェクトの依存関係を管理するファイル
├── Pipfile.lock # Pipfileの依存関係のロックファイル
│
├── mysite/ # プロジェクトの設定ファイル
│ ├── __init__.py
│ ├── settings.py # 設定ファイル
│ ├── urls.py # プロジェクト全体のURLルーティング
│ └── wsgi.py # WSGIアプリケーション
│ └── asgi.py # ASGIアプリケーション(非同期サポート)
│
└── myapp/ # アプリケーションディレクトリ(例: myapp)
├── migrations/ # マイグレーションファイル
├── templates/ # マイグレーションファイル
| ├── __init__.py
| ├── admin.py # 管理サイトの設定
├── __init__.py
├── admin.py # 管理サイトの設定
├── apps.py # アプリケーション設定
├── forms.py # フォームクラスの定義
├── models.py # データベースモデル
├── tests.py # テスト
├── urls.py # アプリケーションのURLルーティング
└── views.py # ビュー関数
9. サーバーの起動と動作確認
最後に、開発サーバーを起動して、CRUD操作が正しく動作するか確認します。
python manage.py runserver
ブラウザで http://127.0.0.1:8000/ にアクセスし、CRUD操作ができることを確認してください。
10. まとめ
以上がDjangoでのCRUD処理を実装する手順です。この手順に従うことで、基本的なデータの作成、表示、更新、削除が可能なアプリケーションを構築できます。次のステップとして、さらに機能を追加したり、デザインを改善したりすることが考えられます。