DjangoのBASE_DIRの意味をわかりやすく解説
- 作成日: 2021-08-16
- 更新日: 2023-12-26
- カテゴリ: Django
DjangoのBASE_DIRの意味をわかりやすく解説
Djangoではプロジェクトの設定をsettings.py
というファイルで管理することが出来ます。
このsettings.py
には色々な設定が書かれていて、Djangoはサイトを動かすさいにこの設定値を参照します。
このsettings.py
にはBASE_DIRという定数があらかじめ定義されています。
このBASE_DIR
という定数はどういう値なのでしょうか?
この記事ではBASE_DIR
の値について詳しく解説していきます。
具体的には↓を見ていきます。
- 解説の前提とするプロジェクト
- BASE_DIRの定義
- __file__とは?
- pathlibとは?
- Pathの簡単な使い方
- BASE_DIRの値の意味
解説の前提とするプロジェクト
今回、解説に使用するDjangoプロジェクトは↓のような構成になっています。
mysite
├── manage.py
└── mysite
├── asgi.py
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
django-admin startproject mysite
で作成した直後の状態です。
BASE_DIRの定義
Django(3.1.7付近)がsettings.py
に定義するBASE_DIR
ですが、↓のような定義になっています。
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
なにやらpathlib
というモジュールのPath
というオブジェクトを使って、__file__
という変数を参照しています。
そしてそれをresolve()
して、parent.parent
という風に属性を参照しています。
BASE_DIR
の定義はこれらのコードの実行結果になります。
つまり、これらのコードを1つずつ見て行けばBASE_DIR
の持つ値の意味がわかるということになります。
__file__とは?
まずは__file__
変数から見ていきます。
__file__
はPythonの組み込みの変数で、これにはファイル名が保存されています。
たとえばsettings.py
内でこの__file__
を参照した場合は、settings.py
のファイル名が保存されるということになります。
具体的にsettings.py
内におけるこの__file__
の値を見てみましょう。
↓のようなコードをsettings.py
に書きます。
print('settings.py: __file__ =', __file__)
そしてpython manage.py
を実行します。
すると筆者の環境では↓のような値が出力されます。
settings.py: __file__ = /to/mysite/settings.py
↑のように__file__
には、__file__
を参照しているファイルのフルパス名が保存されています。
pathlibとは?
関連記事:
Pythonのpathlibの今時な使い方
pathlib
とはパスに関連する問題を解決するモジュールです。
pathlib
にはPath
オブジェクトが定義されていて、一般的にはこのPath
オブジェクトをインポートして使います。
Path
オブジェクトには多数のパスに関連するメソッドが定義されています。
また、属性もあります。
このPath
オブジェクトを操作することでパスの問題を解決することが可能です。
Pathの簡単な使い方
Path
の使い方を見てみます。
まずPath
オブジェクトに__file__
を渡します。
こうすると__file__
の持つパスの値をPath
オブジェクトで管理できるようになります。
path = Path(__file__)
print(path)
# /to/mysite/settings.py
resolve()の意味
Path
オブジェクトのresolve()
はどういうメソッドなんでしょうか?
Path.resolve - pathlib --- オブジェクト指向のファイルシステムパス — Python 3.9.4 ドキュメント
resolve()
はパスを絶対パスに変換します。
そしてあらゆるシンボリックリンクを解決して、リアルなパスにします。
つまり↓のコードは
Path(__file__).resolve()
__file__
の持つ値をresolve()
で解決して、絶対パスに変換しているということになります。
__file__
の値を信用していないコードになるというわけです。
つまり__file__
の値が相対パスだった場合でも絶対パスに変換することで、その後のコードをうまく動作させるという狙いがあります。
ちなみに__file__
の値が必ず絶対パスであるという保証はないようです。なぜならドキュメントには「絶対パス」という記載がないからです。
parentの意味
parent
の属性の意味は、現在のパスの上位ディレクトリの参照です。
PurePath.parent - pathlib --- オブジェクト指向のファイルシステムパス — Python 3.9.4 ドキュメント
__file__
の値がたとえば/aaa/bbb/ccc
だっとします。
そうすると↓のコードは
print(Path('/aaa/bbb/ccc').parent)
# /aaa/bbb
↑のようにparent
1つだけの場合は値は/aaa/bbb
になります。
parent
を2つ繋げた場合は、
print(Path('/aaa/bbb/ccc').parent.parent)
# /aaa
↑のように2つ上のディレクトリが参照されます。
BASE_DIRの値の意味
では以上のことを踏まえてBASE_DIR
の値を見てみます。
BASE_DIR
の値はPath
オブジェクトで生成されます。
Path(__file__)
の__file__
はsettings.py
のパスが保存されていて、それをPath
で管理します。
そしてresolve()
メソッドでパスを絶対パスに変換します。
さらにparent
属性を2回参照して、2つ上のディレクトリを参照します。
つまり↓のコードは、
BASE_DIR = Path(__file__).resolve().parent.parent
print('__file__ =', __file__)
# __file__ = /to/mysite/settings.py
print('BASE_DIR =', BASE_DIR)
# BASE_DIR = /to/mysite
↑のような結果になるわけです。
BASE_DIR
が示しているパスはどこかと言うと、
mysite <---------------- ここがBASE_DIR
├── manage.py
└── mysite
├── asgi.py
├── __init__.py
├── settings.py <--- ここが__file__
├── urls.py
└── wsgi.py
ということになります。
BASE_DIRの使い方
BASE_DIR
はPath
オブジェクトなので、/
でパスを合成することが出来ます。
たとえば↓のようにです。
print(BASE_DIR / 'abc/def.py')
# /to/mysite/abc/def.py
↑のようにすればパスを合成できるので、settings.py
でパスが必要な時はBASE_DIR
の使用を検討してみてください。
おわりに
今回はDjangoのBASE_DIR
について詳しく見てみました。
BASE_DIR
は利用頻度が高いので、あらかじめ定数化されています。
settings.py
を書く機会が増えればBASE_DIR
の使用回数も増えるかもしれません。
🦝 < BASE_DIRはショートカット
🐭 < BASE_DIRを使ってパスを合成しよう