バックエンド開発の準備
バックエンドのルートディレクトリの作成
$ mkdir -p ~/dev/recsys-full/src/backend/
$ cd ~/dev/recsys-full/src/backend/
backend$
データベースの準備
ここでは、データベースにアクセスするユーザ名をrsl、ログインするためのパスワードをrsl-passとしています。適宜、変更してください。
postgres=# CREATE DATABASE recsys_full ENCODING 'UTF8';
postgres=# CREATE ROLE rsl WITH LOGIN PASSWORD 'rsl-pass';
postgres=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-------------------+----------+----------+-----------------+-------------+-------------+------------+-----------+-----------------------
...(略)...
recsys_full | postgres | UTF8 | libc | ja_JP.UTF-8 | ja_JP.UTF-8 | | |
...(略)...
postgres=# ALTER DATABASE recsys_full OWNER TO rsl;
postgres=# \l
List of databases
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
-------------------+----------+----------+-----------------+-------------+-------------+------------+-----------+-----------------------
...(略)...
recsys_full | rsl | UTF8 | libc | ja_JP.UTF-8 | ja_JP.UTF-8 | | |
...(略)...
postgres=# \c recsys_full
recsys_full=# \dt
Did not find any relations.
recsys_full=# CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE EXTENSION
Django のインストール
(recsys_full) backend$ pip install django
(recsys_full) backend$ pip freeze
...(略)...
asgiref==3.12.1
Django==6.1
sqlparse==0.6.0
...(略)...
Django プロジェクトの作成
(recsys_full) backend$ django-admin startproject config .
(recsys_full) backend$ tree
.
├── config
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
2 directories, 6 files
.gitignore の設定
src/backend/.gitignore
__pycache__/
migrations/
logs/
static/
media/
設定ファイル
(recsys_full) backend$ mkdir config/settings/
(recsys_full) backend$ mv config/settings.py config/settings/base.py
(recsys_full) backend$ echo 'from .base import *' > config/settings/development.py
(recsys_full) backend$ tree -a
.
├── .gitignore
├── config
│ ├── __init__.py
│ ├── asgi.py
│ ├── settings
│ │ ├── base.py
│ │ └── development.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
3 directories, 8 files
src/backend/manage.py
...(略)...
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings.development') # <- developmentを追加
...(略)...
if __name__ == '__main__':
main()
src/backend/config/settings/base.py
...(略)...
import os # <- 追加
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent # <- .parentを追加
...(略)...
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY') # <- 修正
...(略)...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.postgres', # <- 追加
]
...(略)...
src/backend/config/settings/development.py
from .base import *
import os
import logging
# ローカル開発専用の既定鍵(DJANGO_SECRET_KEY が未設定の場合のみ使用。本番では使用不可)。
if not SECRET_KEY:
SECRET_KEY = 'django-insecure-local-dev-only-do-not-use-in-production'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'recsys_full',
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': '',
'PORT': '',
}
}
class SQLColorFormatter(logging.Formatter):
LOG_COLOR = "\033[96m"
RESET = "\033[0m"
def format(self, record):
message = super().format(record)
return f"{self.LOG_COLOR}{message}{self.RESET}"
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'colored_sql': {
'()': 'config.settings.development.SQLColorFormatter',
'format': '%(levelname)s %(message)s',
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'colored_sql',
}
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
}
}
}
Django サーバの起動
(recsys_full) backend$
export DB_USER=rsl
export DB_PASSWORD=rsl-pass
(recsys_full) backend$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
DEBUG (0.006) SELECT oid, typarray FROM pg_type WHERE typname = 'hstore'; args=('hstore',); alias=default
DEBUG (0.000) SELECT oid, typarray FROM pg_type WHERE typname = 'citext'; args=('citext',); alias=default
DEBUG (0.007)
SELECT
c.relname,
CASE
WHEN c.relispartition THEN 'p'
WHEN c.relkind IN ('m', 'v') THEN 'v'
ELSE 't'
END,
obj_description(c.oid, 'pg_class')
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('f', 'm', 'p', 'r', 'v')
AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid)
; args=None; alias=default
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
August 29, 2026 - 06:07:11
Django version 6.1, using settings 'config.settings.development'
Starting WSGI development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
WARNING: This is a development server. Do not use it in a production setting. Use a production WSGI or ASGI server instead.
For more information on production servers see: https://docs.djangoproject.com/en/6.1/howto/deployment/
ブラウザで、上記に記載されている URL にアクセスし、「The install worked successfully! Congratulations!」と表示されることを確認してください。
Django の設定
src/backend/config/settings/base.py
...(略)...
LANGUAGE_CODE = 'ja-jp' # <- 修正
TIME_ZONE = 'Asia/Tokyo' # <- 修正
...(略)...
ブラウザで下記 URL にアクセスし、日本語で「インストールは成功しました!おめでとうございます!」と表示されることを確認してください。
参考
- 株式会社オープントーン,佐藤大輔,伊東直喜,上野啓二,『実装で学ぶフルスタック Web 開発 エンジニアの視野と知識を広げる「一気通貫」型ハンズオン』,翔泳社,2023.
- 3-3 バックエンド開発の準備