Pathee engineering blog

世界をしなやかに変えるエンジニアたちのブログ

Django2でのディレクトリ構成について

これはPathee Advent Calendar 2019の8日目の記事です。

Django 3リリース!!!

いきなりですが、Django3がGAになりましたね!

www.djangoproject.com

でも残念!この記事は2系ベースだよ!!

(´・ω・`)

偶然なんですが、PHPで開発していたときもPhalconが3に上がったりしたので、またかと思いもしています。

なんでDjangoの話?

Patheeのプロダクトのバックエンドは、Djangoと同じくPythonフレームワークであるFlaskで実装されているのですが、 管理画面のフルリプレイスを検討した結果、Djangoでいってみよう!ということにしたので、実はDjangoでもプロダクト開発をしているからです。

Djangoを触ってみて最初に戸惑ったのが、プロジェクト(django-admin startproject)とアプリケーション(django-admin startapp)のテンプレートコードが生成される場所でした。 チュートリアルの通りに進めていくのは、管理と把握しづらさが抜けなかったので、 いくつかの記事やプロダクトを参考にさせてもらいながら、私がたどり着いた構成は以下になります。

ディレクトリ構成

とりあえずtree結果を、はいドーン!

プロジェクトルート
├── 外部スタイルテンプレートプロジェクト
├── config
│   └── settings
├── frontend
│   └── src
│       ├── @types
│       ├── components
│       │   ├── groups
│       │   └── parts
│       ├── containers
│       └── domains
├── migration
│   ├── DB単位
│   │   ├── drivers
│   │   ├── environments
│   │   └── scripts
│   └── mybatis-migrations
│       ├── bin
│       └── lib
├── mysql
│   ├── conf.d
│   ├── sql
│   └── tmp
│       └── data
├── nginx
├── shell
└── src
    ├── apps
    │   ├── ドメイン単位
    │   │   ├── forms
    │   │   ├── migrations
    │   │   └── models
    │   ...
    │   └── user
    │       └── migrations
    ├── core
    ├── static
    │   ├── 外部スタイルテンプレートの生成先
    │   │   └── assets
    │   ├── css
    │   ├── fonts
    │   ├── images
    │   ├── js
    │   └── sass
    └── templates
        ├── account
        ├── ドメイン単位
        ...
        └── user

Docker Composeで開発できるようにしており、Composeファイルは以下のようになっています。

version: '3.7'
services:
  app:
    build:
      context: .
    image: プロジェクト名/app
    container_name: プロジェクト名_app
    command: /bin/bash -c "/bin/bash"
    tty: true
    working_dir: "/pathee/プロジェクト名"
    env_file:
      - ./.envs/.local/.app
    volumes:
      - .:/pathee/プロジェクト名:cached
    ports:
      - "8000:8000"
      - "35729:35729"
    depends_on:
      - db

  db:
    image: mysql:8
    container_name: プロジェクト名_db
    environment:
      MYSQL_ROOT_PASSWORD: "root"
      MYSQL_USER: "admin"
      MYSQL_PASSWORD: "admin"
    volumes:
      - ./mysql/sql:/docker-entrypoint-initdb.d
      - ./mysql/conf.d:/etc/mysql/conf.d
      - ./mysql/data:/var/lib/mysql
      - ./mysql/tmp/data:/tmp/data
      - ./mysql/log:/var/log/mysql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    ports:
      - "3306:3306"

  migration:
    build:
      context: ./migration/
    image: プロジェクト名/migration
    container_name: プロジェクト名_migration
    command: /bin/bash
    tty: true
    working_dir: "/pathee/migration"
    volumes:
      - ./migration:/pathee/migration:cached
    depends_on:
      - db

構成の解説

やろうとしていることは、以下のようなことです。

  • リポジトリ名がプロジェクト名なので、startprojectで生成する名前はconfigにする
    • ローカル起動とサーバ起動での設定を分ける
    • config/settingsに基本設定となるbase.pyを作成し、環境差分をlocal.pyとproduction.pyに記載する
    • manage.pyを修正し、デフォルト起動はローカル設定になるようにする
  • WebサーバにはNginx Unitを利用する
  • データベースのマイグレーションを手動で制御したかったので、開発中はDjangoマイグレーションを利用するが、DBサーバに適用する際はMyBatis Migrationsを利用する
  • アプリケーションのコード生成先はsrcディレクトリ配下にする
    • manage.pyを修正し、src配下をアプリケーションのディレクトリにする
    current_path = os.path.dirname(os.path.abspath(__file__))
    sys.path.append(os.path.join(current_path, "src"))

こうした理由

チュートリアルのままだとイマイチディレクトリの役割が分かりづらかったのと、グルーピングされている感じがなかったので、このようにしました。 プロジェクトルート配下にディレクトリが増えていくのも、nginxやmysqlなどのディレクトリがあるため、ソースコードソースコードで分けておきたかったのもあります。

トランスパイルに関しては、当初使わずにやっていくつもりだったReactを結局使うことになったからです。。。

こうしてみると個人的にはだいぶ見通しが良くなったので、Djangoを利用する際には思い出してみてください。

まあ、2系の話なんですけどねっ