本編に収まりにくい開発者向けの補足——カスタム管理コマンド、静的資産(Sortable.js・日本語フォント)、Django 管理サイト(admin)設定、カスタムエラーページ、ビルドコンテキスト整理——をまとめたドキュメントです。
このドキュメントは旧
specs/60_補足資料.mdを、現行コード(各admin.py/dashboard/management/commands//static//templates/404.html/orders/views.py/.dockerignore)と照合して再構成したものです。旧手順書との差異は本文中に「実装メモ」として注記しています。
現行コードには、デバッグ・リセット・データ補填用のカスタム管理コマンドがあります。
packaging_snapshot(状態ダンプ)パッケージング(注文・引当・袋・梱包・梱包計画)の現在状態を、重量・空き容量(headroom)込みで JSON として標準出力するデバッグ用コマンドです。
docker compose -f docker-compose.dev.yml exec app python manage.py packaging_snapshot
settings(PACKAGE_MAX_WEIGHT_KG / DEFAULT_BOX_WEIGHT_KG)、product_weights、prepared_groups、宛先ごとの destinations[].packages(箱の現在重量・空き容量)、placeholders(remaining = ordered − (allocated + packaged + planned_total))が含まれます。NEW / ACCEPTED / PACKED / SHIPPED / DELIVERED で、CANCELED は対象外です。実装メモ: コマンド内の
getattr(settings, "PACKAGE_MAX_WEIGHT_KG", 25.0)/getattr(..., "DEFAULT_BOX_WEIGHT_KG", 0.0)のフォールバック値(25.0/0.0)は、現行config/settings.pyに両定数が定義されている(20.0/0.5)ため実際には使われません。出力されるsettings値は settings の現行値になります(→ 共通基盤 §1.5)。
backfill_credit_from_carryover(繰越残高台帳の補填)orders/management/commands/backfill_credit_from_carryover.py。Issue #13 の繰越残高台帳導入前に作られた PaymentAdjustment(action=CARRY_OVER) を、CustomerCreditTransaction(CARRY_OVER_FROM_CANCELED_ORDER) として台帳へ反映する補填コマンドです。
docker compose -f docker-compose.dev.yml exec app python manage.py backfill_credit_from_carryover
docker compose -f docker-compose.dev.yml exec app python manage.py backfill_credit_from_carryover --dry-run
payment_adjustment が既に台帳に紐づいている場合はスキップするため、複数回実行しても二重加算しません。--dry-run では対象を表示し、書き込みはロールバックします。created_by は NULL になります。clear_orders(注文系データの全削除)⚠️注文関連テーブル(orders_packageitem / orders_packageplanitem / orders_allocation / orders_package / orders_orderitem / orders_order / orders_bag)を TRUNCATE し、在庫の products_stock.total_ordered_kg を 0 にリセットする破壊的コマンドです。実行時に yes の対話確認を求めます。
docker compose -f docker-compose.dev.yml exec app python manage.py clear_orders
⚠️ 警告: 注文・引当・梱包データが全件・復元不可能で削除されます。開発環境でのリセット用途を想定したもので、本番では実行しないでください。外部キー制約を一時無効化(
SET FOREIGN_KEY_CHECKS=0)してTRUNCATEする MySQL 前提の実装です。
⚠️ 途中失敗時の非原子性: このコマンドは
transactionを import していますがtransaction.atomic()は使っておらず、各 SQL を逐次実行します。さらに MySQL のTRUNCATEは通常のDELETEと異なりトランザクションでロールバックできません。したがって途中の SQL が失敗すると「一部テーブルだけ空になった」「注文データと在庫集計(total_ordered_kg)の整合が崩れた」状態になり得ます。実行前に DB バックアップ/スナップショットを取得し、途中失敗時は手動復旧が必要になる前提で扱ってください。
実装メモ:
clear_ordersは旧specs/60には記載がなく、現行コードにのみ存在します。破壊的データ操作という性質上、データ移行・初期化の観点は operations/データ移行 とあわせて扱います。
請求書 PDF は xhtml2pdf(pisa)で生成します(orders/views.py の generate_invoice_pdf)。日本語表示のため IPAex ゴシックを使用します。
static/fonts/ipaexg.ttf。templates/orders/invoice_template.html の @font-face(font-family: 'IPAexGothic'; src: url("fonts/ipaexg.ttf");)。orders/views.py の link_callback が django.contrib.staticfiles.finders で URI を実ファイルへ解決し、pisa.CreatePDF(..., link_callback=link_callback) に渡します。実装メモ:
static/fonts/にはipaexg.ttfのほかipaexm.ttf(明朝)や配布アーカイブ(IPAexfont00401.zipと展開フォルダ)も置かれていますが、現行コードが参照するのはipaexg.ttfのみです。
static/vendor/sortablejs/sortable.min.js(LICENSE も同梱)。実装メモ: 現状、
sortable.min.jsを読み込んでいるテンプレート/JS は見当たりませんでした({% static %}等での参照なし)。ファイルは存在するが現行コードからは未参照の状態です。自動引当ボードの現在の実装は features/出荷ワークフロー を参照してください。
業務画面とは別に、Django 標準の管理サイト(/admin/)でも主要モデルを編集できます。admin.py を設定しているアプリは以下です(他アプリの admin.py は実質空)。
accounts/admin.pyUser を BaseUserAdmin ベースで登録し、Destination を TabularInline で同一画面編集。CustomUserCreationForm、add_fieldsets は ('username', 'password1', 'password2')。Media.js = ('accounts/js/admin_password_toggle.js',) でパスワード表示トグルの JS を読み込み(実体は accounts/static/accounts/js/admin_password_toggle.js)。実装メモ: 旧手順書の
add_fieldsetsは('username', 'password',)でしたが、現行は標準の('username', 'password1', 'password2')(確認用パスワード付き)です。
orders/admin.pyOrder(OrderItem をインライン)、Bag、Package、PackageItem を登録。OrderAdmin.list_display / list_filter は status と payment_status を使用。BagAdmin は get_order_item(allocation→order_item を辿る)を一覧に表示。実装メモ: 旧手順書は入金状態を
is_paidで表示していましたが、現行モデルはpayment_status(入金ステータス)に変わっており、admin もそれに追随しています(→ features/注文管理)。
products/admin.pyProductVariety / Product / Stock を登録。StockAdmin.list_display は ('variety', 'total_supplied_kg', 'total_ordered_kg', 'available_kg', 'updated_at')。available_kg はプロパティを表示用メソッドで露出。実装メモ: 旧手順書の
StockAdminは('variety', 'weight_kg', 'updated_at')でしたが、現行の在庫モデルは「総供給量 − 総注文量 = 利用可能量」を持つ構造になっており、admin もその 3 値(供給・注文・利用可能)を表示します(→ features/商品在庫マスタ)。
system_settings/admin.pySystemSetting(BankAccount をインライン)を登録。シングルトン運用で、has_add_permission は未作成時のみ True、has_delete_permission は常に False。response_add / response_change を上書きし、保存後は一覧へ戻す(「保存してもう一つ追加」を抑止)。display_name_link で shop_name が空でも編集画面へのリンクを表示。templates/404.html は base.html を継承し、トップ(products:product_list)への導線を持つカスタム 404 ページです。DEBUG=False のとき Django が自動的に使用します。
.dockerignore は Docker イメージのビルドコンテキストから不要・秘匿ファイルを除外します(.git / __pycache__ / IDE 設定 / .env / env.production / db_data/ / staticfiles/ 等)。詳細な役割は 開発環境構築 §2 も参照。
実装メモ(現行
.dockerignoreの留意点):
docker-compose.prod.ymlを除外対象に挙げていますが、リポジトリに該当ファイルは存在しません(本番用はdocker-compose.yml)。- ドキュメント除外を意図した行が
spec/になっていますが、実ディレクトリはspecs/のため、この指定では除外が効きません(specs/はビルドコンテキストに含まれます)。実害は小さいものの、意図どおり除外したい場合はspecs/への修正が必要です。
specs/60_補足資料.sync-conflict-20251013-085026-GYLYR7T.md が存在しますが、正規版 specs/60_補足資料.md と差分を確認したところ、system_settings/admin.py の display_name_link 等が未反映の古い版でした。正規版のほうが現行コードに近く、sync-conflict 側に取り込むべき追加情報はありません。移行対象外とします(specs棚卸し表 参照)。
.dockerignore・静的ファイル設定 → development/開発環境構築元資料: specs/60_補足資料.md(および sync-conflict 版)を現行コード(accounts/admin.py, orders/admin.py, products/admin.py, system_settings/admin.py, dashboard/management/commands/packaging_snapshot.py, dashboard/management/commands/clear_orders.py, static/vendor/sortablejs/, static/fonts/, templates/404.html, templates/orders/invoice_template.html, orders/views.py, .dockerignore)と照合して再構成
関連: README, specs棚卸し表, Issue #1