静的ファイルの設定
Djangoでは、CSS、JavaScript、画像、サードパーティ製のフロントエンドライブラリなど、あらかじめ用意されたリソースを「静的ファイル」と呼びます。デフォルトでは、プロジェクトルート直下にstaticフォルダを作成し、そこにこれらのリソースを配置することが推奨されます。さらに管理を容易にするため、css、js、imgなどのサブフォルダで区分けするのが一般的です。
settings.pyでの設定例を以下に示します。
import os
# 静的ファイルへのアクセスプレフィックス(URLの一部)
STATIC_URL = '/assets/'
# 静的ファイルが配置されている実際のファイルシステムパス
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
os.path.join(BASE_DIR, 'resources'), # 複数のディレクトリを指定可能
]
テンプレート内で静的ファイルを読み込む際は、動的なパス生成を利用することで、設定変更に強い実装が可能です。まず{% load static %}を宣言し、{% static 'パス' %}タグを使用します。
{% load static %}
<!-- 動的パスによるリソース読み込み -->
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<script src="{% static 'js/main.js' %}"></script>
requestオブジェクトの活用
Djangoのビュー関数は必ずHttpRequestオブジェクトを引数として受け取ります。このオブジェクトを通じて、クライアントからのリクエスト情報(メソッド種別、送信データなど)にアクセスできます。
リクエストメソッドの判別
リクエストがGETかPOSTかを判別するには、request.methodプロパティを参照します。この値は文字列(例:'GET', 'POST')で返されます。
POSTデータの取得
フォームから送信されたデータを取得するにはrequest.POSTを使用します。これは辞書ライクなオブジェクトです。キーを指定して値を取得する際、getメソッドを使うと単一の値が、getlistメソッドを使うとリスト形式で値を取得できます。
def process_form(request):
if request.method == 'POST':
# 単一の値を取得(リストの最後の要素、または存在しない場合はNone)
username = request.POST.get('user_name')
# 複数の値を取得(チェックボックスなど)
selected_items = request.POST.getlist('items')
# 処理ロジック...
注意点: POSTリクエストを行う際、CSRF(Cross Site Request Forgery)対策が有効になっていると403エラーが発生する場合があります。開発段階で検証する場合は、settings.pyのMIDDLEWARE設定から'django.middleware.csrf.CsrfViewMiddleware'を一時的にコメントアウトするか、テンプレート側でCSRFトークンを適切に埋め込む必要があります。
データベース接続の設定(PyMySQL)
Djangoデフォルトのデータベースドライバではなく、Python純正のMySQLコネクタであるPyMySQLを使用する手順を解説します。
まず、settings.pyのDATABASES設定を以下のように変更します。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'my_project_db', # データベース名
'USER': 'db_admin', # ユーザー名
'PASSWORD': 'secure_pass', # パスワード
'HOST': '127.0.0.1', # ホスト
'PORT': '3306', # ポート
'CHARSET': 'utf8mb4', # 文字コード
}
}
次に、プロジェクトフォルダ(settings.pyと同階層)またはアプリケーションフォルダ直下の__init__.pyに、以下のコードを記述してDjangoにPyMySQLの使用を指示します。
import pymysql
# MySQLdbの代わりにPyMySQLを使用するよう設定
pymysql.install_as_MySQLdb()
Django ORMの基礎
ORM(Object-Relational Mapping)を利用することで、SQLを直接記述せずにPythonオブジェクトとしてデータベース操作を行えます。
モデルの定義
アプリケーションディレクトリ内のmodels.pyでクラスを定義します。ここでは例として「従業員」を管理するモデルを作成します。
from django.db import models
class Employee(models.Model):
# idフィールドは主キーとして自動的に追加されます(明示的な定義も可能)
full_name = models.CharField(max_length=100) # 名前
email_address = models.EmailField(max_length=255) # メールアドレス
job_title = models.CharField(max_length=64) # 役職
def __str__(self):
return f"{self.full_name} ({self.job_title})"
データベースのマイグレーション
モデルの変更をデータベースに反映させるには、以下の2つのコマンドを実行します。
python manage.py makemigrations: モデルの変更内容を検出し、マイグレーションファイル(変更履歴)を作成します。python manage.py migrate: マイグレーションファイルを基に、実際のデータベーススキーマを更新します。
フィールドの追加と削除
既存のテーブルに新しいフィールドを追加する場合、デフォルト値が設定されていないとエラーになります。その際は、default値を設定するか、null=Trueを指定してNULLを許容する必要があります。
CRUD機能の実装
ORMを使用したデータの検索、登録、更新、削除の具体的な実装例を示します。
認証機能の実装
ユーザーからの入力を受け取り、データベース内のレコードと照合するログイン処理です。
from django.shortcuts import render, HttpResponse
from . import models
def login_view(request):
if request.method == 'POST':
input_email = request.POST.get('email')
input_pass = request.POST.get('password')
# filterメソッドで条件に合うレコードを検索
# first()を呼ぶことでクエリセットから最初のオブジェクトを取得
user_obj = models.Employee.objects.filter(email_address=input_email).first()
if user_obj:
# 実際のアプリケーションではハッシュ化されたパスワードの比較が必要
if user_obj.password == input_pass:
return HttpResponse('ログインに成功しました')
else:
return HttpResponse('パスワードが間違っています')
else:
return HttpResponse('該当するユーザーが見つかりません')
return render(request, 'login.html')
データ一覧の表示と新規登録
データベースから全件取得して表示し、新しいレコードを追加する機能です。
def employee_list(request):
# objects.all()ですべてのレコードを取得
all_employees = models.Employee.objects.all()
return render(request, 'list.html', {'employees': all_employees})
def add_employee(request):
if request.method == 'POST':
name = request.POST.get('full_name')
role = request.POST.get('role')
# createメソッドで新しいレコードを作成・保存
models.Employee.objects.create(
full_name=name,
job_title=role
)
# 登録後は一覧ページへリダイレクト
return redirect('/list/')
return render(request, 'add.html')
データの編集と削除
既存のレコードを修正・削除する処理です。URLパラメータを利用して対象のIDを受け取ります。
def edit_employee(request):
# GETパラメータから編集対象のIDを取得
target_id = request.GET.get('id')
# IDに基づいて対象オブジェクトを取得
emp_instance = models.Employee.objects.filter(id=target_id).first()
if request.method == 'POST':
new_name = request.POST.get('full_name')
new_role = request.POST.get('role')
# updateメソッドで条件に合うレコード(複数可)を一括更新
models.Employee.objects.filter(id=target_id).update(
full_name=new_name,
job_title=new_role
)
return redirect('/list/')
return render(request, 'edit.html', {'target_emp': emp_instance})
def delete_employee(request):
del_id = request.GET.get('id')
# deleteメソッドで条件に合うレコードを削除
models.Employee.objects.filter(id=del_id).delete()
return redirect('/list/')
テンプレート側では、編集や削除を行うボタンにIDを含むURLを設定します。
<tbody>
{% for emp in employees %}
<tr>
<td>{{ emp.full_name }}</td>
<td>{{ emp.job_title }}</td>
<td>
<!-- GETパラメータでIDを渡す -->
<a href="/edit/?id={{ emp.id }}">編集</a>
<a href="/delete/?id={{ emp.id }}">削除</a>
</td>
</tr>
{% endfor %}
</tbody>