Django開発環境構築(mac)

Djangoの導入

macに標準で入っているpythonのバージョンは古くてDjangoを動かせないらしいので、最新版を導入しておく。導入方法を紹介している記事は多数あるのでここでは省略するが、python japanがわかりやすい。このサイトには仮想環境構築まで載っているのでそれも把握しておく。

python導入後のバージョン確認。(django)という仮想環境を作成しactivateする。

 107:38:56 ~/proj/study $ python3 -V
 2Python 3.9.2
 307:39:02 ~/proj/study $ python3 -m venv django
 407:40:48 ~/proj/study $ ls
 5django
 607:40:57 ~/proj/study $ cd *
 707:41:04 ~/proj/study/django $ ls
 8bin		include		lib		pyvenv.cfg
 907:41:28 ~/proj/study/django $ . bin/activate
10(django) 07:41:39 ~/proj/study/django $

Djangoをpipで導入してバージョン確認。

 1(django) 07:41:51 ~/proj/study/django $ pip install django
 2Collecting django
 3  Downloading Django-3.1.7-py3-none-any.whl (7.8 MB)
 4     |████████████████████████████████| 7.8 MB 1.5 MB/s
 5Collecting sqlparse>=0.2.2
 6  Downloading sqlparse-0.4.1-py3-none-any.whl (42 kB)
 7     |████████████████████████████████| 42 kB 812 kB/s
 8Collecting pytz
 9  Downloading pytz-2021.1-py2.py3-none-any.whl (510 kB)
10     |████████████████████████████████| 510 kB 1.8 MB/s
11Collecting asgiref<4,>=3.2.10
12  Downloading asgiref-3.3.1-py3-none-any.whl (19 kB)
13Installing collected packages: sqlparse, pytz, asgiref, django
14Successfully installed asgiref-3.3.1 django-3.1.7 pytz-2021.1 sqlparse-0.4.1
15(django) 07:42:37 ~/proj/study/django $ django-admin version
163.1.7

django-admin startprojectコマンドでDjangoプロジェクトを作成。プロジェクトの中身を確認。

 1(django) 07:47:18 ~/proj/study/django $ django-admin startproject quick_django
 2(django) 07:47:38 ~/proj/study/django $ ls
 3bin		include		lib		pyvenv.cfg	quick_django
 4(django) 07:47:43 ~/proj/study/django $ cd qui*
 5(django) 07:48:03 ~/proj/study/django/quick_django $ tree
 6.
 7├── db.sqlite3
 8├── main
 9│   ├── __init__.py
10│   ├── __pycache__
11│   │   ├── __init__.cpython-39.pyc
12│   │   ├── admin.cpython-39.pyc
13│   │   ├── apps.cpython-39.pyc
14│   │   └── models.cpython-39.pyc
15│   ├── admin.py
16│   ├── apps.py
17│   ├── migrations
18│   │   ├── __init__.py
19│   │   └── __pycache__
20│   │       └── __init__.cpython-39.pyc
21│   ├── models.py
22│   ├── tests.py
23│   └── views.py
24├── manage.py
25└── quick_django
26    ├── __init__.py
27    ├── __pycache__
28    │   ├── __init__.cpython-39.pyc
29    │   ├── settings.cpython-39.pyc
30    │   ├── urls.cpython-39.pyc
31    │   └── wsgi.cpython-39.pyc
32    ├── asgi.py
33    ├── settings.py
34    ├── urls.py
35    └── wsgi.py
36
376 directories, 23 files
3808:16:02 ~/proj/study/django/quick_django $

quick_django/settings.pyを開いて、作成したmainアプリを認識できるように追記する。 プロジェクト言語とタイムゾーンも変更しておく。

 1# Application definition
 2
 3INSTALLED_APPS = [
 4    'main.apps.MainConfig',
 5    'django.contrib.admin',
 6    'django.contrib.auth',
 7    'django.contrib.contenttypes',
 8    'django.contrib.sessions',
 9    'django.contrib.messages',
10    'django.contrib.staticfiles',
11]
12
13(中略)
14
15LANGUAGE_CODE = 'ja'
16 
17TIME_ZONE = 'Asia/Tokyo'

アプリを実行してみる。警告らしきものが出るが、とりあえず無視。

 1(django) 07:55:41 ~/proj/study/django/quick_django $ python manage.py runserver
 2Watching for file changes with StatReloader
 3Performing system checks...
 4
 5System check identified no issues (0 silenced).
 6
 7You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
 8Run 'python manage.py migrate' to apply them.
 9March 15, 2021 - 07:55:56
10Django version 3.1.7, using settings 'quick_django.settings'
11Starting development server at http://127.0.0.1:8000/
12Quit the server with CONTROL-C.
13[15/Mar/2021 07:56:48] "GET / HTTP/1.1" 200 16505
14[15/Mar/2021 07:56:48] "GET /static/admin/css/fonts.css HTTP/1.1" 200 423
15[15/Mar/2021 07:56:49] "GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1" 200 85876
16[15/Mar/2021 07:56:49] "GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1" 200 85692
17[15/Mar/2021 07:56:49] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184
18Not Found: /favicon.ico
19[15/Mar/2021 07:56:49] "GET /favicon.ico HTTP/1.1" 404 1978

[上記7行目の翻訳]
18の未適用の移行があります。 管理者、認証、コンテンツタイプ、セッションなどのアプリに移行を適用するまで、プロジェクトが正しく機能しない場合があります。

Apache最新化

ApacheでDjangoアプリを実行するための環境整備。macではApache httpdが標準装備されている。 ただし、古いとDjangoが正しく動作しないとの記事を見かけたので、最新を導入しておく。

Homebrewの導入

Homebrew を使うので、入っていなければ以下サイトなどを参考に導入する。
Xcodeでcommand line toolsの導入・確認方法を徹底解説します!
Macの開発を便利にするパッケージ管理ソフト Homebrew の導入手順

導入されていることを確認する。

1(django) 07:35:56 ~/proj/study/django/quick_django $ which brew
2/usr/local/bin/brew

Apacheの導入

Apache httpdが入っていることを確認。

1(django) 08:07:50 ~/proj/study/django/quick_django $ which httpd
2/usr/sbin/httpd

Apache httpd のバージョンを確認しておく。(/usr/sbinが環境変数PATHに設定済みであれば、以下、/usr/sbinの打ち込みは省略可)

1(django) 08:08:10 ~/proj/study/django/quick_django $ /usr/sbin/httpd -version
2Server version: Apache/2.4.34 (Unix)
3Server built:   Feb 22 2019 20:20:11

brew install httpdを叩いて最新版を導入できる。

ログは長いので折りたたんでおく
  1(django) 07:38:42 ~/proj/study/django/quick_django $ brew install httpd
  2Updating Homebrew...
  3==> Auto-updated Homebrew!
  4Updated 3 taps (homebrew/core, homebrew/cask and homebrew/services).
  5==> New Formulae
  6as-tree                    libpipeline                qt-mariadb
  7bas55                      libunwind                  qt-mysql
  8crispy-doom                lttng-ust                  qt-percona-server
  9delve                      numactl                    qt-postgresql
 10enzyme                     openmama                   qt-unixodbc
 11geph4                      openmodelica               rdkit
 12glibc                      oras                       snowpack
 13gopass-jsonapi             projectm                   sqlancer
 14haskell-language-server    pyqt-3d                    threemux
 15iconsur                    pyqt-builder               tomcat@9
 16kertish-dfs                pyqt-networkauth           wllvm
 17klee                       pyside@2                   xray
 18kotlin-language-server     python-tabulate            zlib-ng
 19latino                     qt-libiodbc
 20==> Updated Formulae
 21Updated 1140 formulae.
 22==> Renamed Formulae
 23libsasl2 -> cyrus-sasl                   pyqt5 -> pyqt@5
 24minizip2 -> minizip-ng                   qt5 -> qt@5
 25==> Deleted Formulae
 26avian                                    geant4
 27==> New Casks
 28airbuddy                   evkey                      nuage
 29around                     finisher-fluxx             plasticscm-cloud-edition
 30atomic-wallet              foobar2000                 remnote
 31banksiagui                 goldenpassport             rhino
 32celestia                   internxt-drive             simplelink-msp432-sdk
 33cinderella                 jandi-statusbar            simplelink-msp432e4-sdk
 34clicker-for-netflix        kyokan-bob                 skychart
 35clicker-for-youtube        mailtrackerblocker         swiftbar
 36code-composer-studio       megax                      the-archive
 37cog                        micro-sniff                uniflash
 38daedalus-testnet           mouse-fix                  veepn
 39devbook                    mxsrvs                     volanta
 40devutils                   n1ghtshade                 zecwallet-lite
 41dnagedcom                  neat-reader                zulufx
 42==> Updated Casks
 43Updated 622 casks.
 44==> Deleted Casks
 45ableton-live               kode54-cog                 pins
 46daedalus-catalyst          mega                       protonmail-unofficial
 47insomnia-designer          mist                       rhinoceros
 48
 49==> Downloading https://homebrew.bintray.com/bottles/apr-1.7.0_2.mojave.bottle.t
 50==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/4627416a5d9c651d2d4fb
 51######################################################################## 100.0%
 52==> Downloading https://homebrew.bintray.com/bottles/apr-util-1.6.1_3.mojave.bot
 53==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/b3b8376d8f481164a34b8
 54######################################################################## 100.0%
 55==> Downloading https://homebrew.bintray.com/bottles/brotli-1.0.9.mojave.bottle.
 56==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/d121eaa3e670d5ad97251
 57######################################################################## 100.0%
 58==> Downloading https://homebrew.bintray.com/bottles/c-ares-1.17.1.mojave.bottle
 59######################################################################## 100.0%
 60==> Downloading https://homebrew.bintray.com/bottles/jemalloc-5.2.1_1.mojave.bot
 61==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/d3f6f85e74b08c8c97448
 62######################################################################## 100.0%
 63==> Downloading https://homebrew.bintray.com/bottles/libev-4.33.mojave.bottle.ta
 64######################################################################## 100.0%
 65==> Downloading https://homebrew.bintray.com/bottles/nghttp2-1.43.0.mojave.bottl
 66==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/cbcac00ca57c0c71e1481
 67######################################################################## 100.0%
 68==> Downloading https://homebrew.bintray.com/bottles/httpd-2.4.46_2.mojave.bottl
 69==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/b88153894953fa0c976f0
 70######################################################################## 100.0%
 71==> Installing dependencies for httpd: apr, apr-util, brotli, c-ares, jemalloc, libev and nghttp2
 72==> Installing httpd dependency: apr
 73==> Pouring apr-1.7.0_2.mojave.bottle.tar.gz
 74==> Caveats
 75apr is keg-only, which means it was not symlinked into /usr/local,
 76because Apple's CLT provides apr.
 77
 78If you need to have apr first in your PATH, run:
 79  echo 'export PATH="/usr/local/opt/apr/bin:$PATH"' >> /Users/fuku/.bash_profile
 80
 81For compilers to find apr you may need to set:
 82  export LDFLAGS="-L/usr/local/opt/apr/lib"
 83  export CPPFLAGS="-I/usr/local/opt/apr/include"
 84
 85==> Summary
 86🍺  /usr/local/Cellar/apr/1.7.0_2: 104 files, 1.4MB
 87==> Installing httpd dependency: apr-util
 88==> Pouring apr-util-1.6.1_3.mojave.bottle.tar.gz
 89==> Caveats
 90apr-util is keg-only, which means it was not symlinked into /usr/local,
 91because Apple's CLT provides apr (but not apr-util).
 92
 93If you need to have apr-util first in your PATH, run:
 94  echo 'export PATH="/usr/local/opt/apr-util/bin:$PATH"' >> /Users/fuku/.bash_profile
 95
 96==> Summary
 97🍺  /usr/local/Cellar/apr-util/1.6.1_3: 54 files, 771.1KB
 98==> Installing httpd dependency: brotli
 99==> Pouring brotli-1.0.9.mojave.bottle.tar.gz
100🍺  /usr/local/Cellar/brotli/1.0.9: 25 files, 2.3MB
101==> Installing httpd dependency: c-ares
102==> Pouring c-ares-1.17.1.mojave.bottle.tar.gz
103🍺  /usr/local/Cellar/c-ares/1.17.1: 85 files, 548KB
104==> Installing httpd dependency: jemalloc
105==> Pouring jemalloc-5.2.1_1.mojave.bottle.tar.gz
106🍺  /usr/local/Cellar/jemalloc/5.2.1_1: 16 files, 1.9MB
107==> Installing httpd dependency: libev
108==> Pouring libev-4.33.mojave.bottle.tar.gz
109🍺  /usr/local/Cellar/libev/4.33: 12 files, 446.1KB
110==> Installing httpd dependency: nghttp2
111==> Pouring nghttp2-1.43.0.mojave.bottle.tar.gz
112🍺  /usr/local/Cellar/nghttp2/1.43.0: 24 files, 2.6MB
113==> Installing httpd
114==> Pouring httpd-2.4.46_2.mojave.bottle.tar.gz
115==> Caveats
116DocumentRoot is /usr/local/var/www.
117
118The default ports have been set in /usr/local/etc/httpd/httpd.conf to 8080 and in
119/usr/local/etc/httpd/extra/httpd-ssl.conf to 8443 so that httpd can run without sudo.
120
121To have launchd start httpd now and restart at login:
122  brew services start httpd
123Or, if you don't want/need a background service you can just run:
124  apachectl start
125==> Summary
126🍺  /usr/local/Cellar/httpd/2.4.46_2: 1,657 files, 27.2MB
127==> `brew cleanup` has not been run in 30 days, running now...
128Removing: /Users/fuku/Library/Caches/Homebrew/gdbm--1.18.1_1.mojave.bottle.tar.gz... (203.3KB)
129Removing: /Users/fuku/Library/Caches/Homebrew/hugo--0.80.0.mojave.bottle.tar.gz... (36.2MB)
130Removing: /usr/local/Cellar/msgpack/3.2.1... (757 files, 5.2MB)
131Removing: /usr/local/Cellar/openssl@1.1/1.1.1d... (7,983 files, 17.9MB)
132Removing: /usr/local/Cellar/openssl@1.1/1.1.1i... (8,067 files, 18.4MB)
133Removing: /Users/fuku/Library/Caches/Homebrew/openssl@1.1--1.1.1i.mojave.bottle.tar.gz... (5.4MB)
134Removing: /Users/fuku/Library/Caches/Homebrew/openssl@1.1--1.1.1j.mojave.bottle.tar.gz... (5.4MB)
135Removing: /Users/fuku/Library/Caches/Homebrew/sqlite--3.34.0.mojave.bottle.tar.gz... (2.0MB)
136Removing: /Users/fuku/Library/Logs/Homebrew/tree... (64B)
137Removing: /Users/fuku/Library/Logs/Homebrew/hugo... (64B)
138Pruned 0 symbolic links and 2 directories from /usr/local
139==> Caveats
140==> apr
141apr is keg-only, which means it was not symlinked into /usr/local,
142because Apple's CLT provides apr.
143
144If you need to have apr first in your PATH, run:
145  echo 'export PATH="/usr/local/opt/apr/bin:$PATH"' >> /Users/fuku/.bash_profile
146
147For compilers to find apr you may need to set:
148  export LDFLAGS="-L/usr/local/opt/apr/lib"
149  export CPPFLAGS="-I/usr/local/opt/apr/include"
150
151==> apr-util
152apr-util is keg-only, which means it was not symlinked into /usr/local,
153because Apple's CLT provides apr (but not apr-util).
154
155If you need to have apr-util first in your PATH, run:
156  echo 'export PATH="/usr/local/opt/apr-util/bin:$PATH"' >> /Users/fuku/.bash_profile
157
158==> httpd
159DocumentRoot is /usr/local/var/www.
160
161The default ports have been set in /usr/local/etc/httpd/httpd.conf to 8080 and in
162/usr/local/etc/httpd/extra/httpd-ssl.conf to 8443 so that httpd can run without sudo.
163
164To have launchd start httpd now and restart at login:
165  brew services start httpd
166Or, if you don't want/need a background service you can just run:
167  apachectl start
168(django) 07:45:20 ~/proj/study/django/quick_django $

再度、httpdの在り処とバージョンを確認しておく。

1(django) 07:56:01 ~/proj/study/django/quick_django $ which httpd
2/usr/local/bin/httpd
3(django) 07:56:52 ~/proj/study/django/quick_django $ /usr/local/bin/httpd -version
4Server version: Apache/2.4.46 (Unix)
5Server built:   Jan 16 2021 08:19:04
6(django) 07:57:19 ~/proj/study/django/quick_django $

バージョンが上がっていることを確認。
httpdの在り処が変わっていた。(仮想環境で導入したから?)

macでは httpd の起動停止を制御する apachectl も標準装備されている。

1(django) 08:08:00 ~/proj/study/django/quick_django $ which apachectl
2/usr/sbin/apachectl

Apacht httpd を起動してみる。

1(django) 08:08:24 ~/proj/study/django/quick_django $ sudo /usr/sbin/apachectl start
2Password:

ブラウザで http://localhost にアクセスして、「It works!」という初期画面が表示されることを確認。

Apache httpd を停止する。

1(django) 08:09:22 ~/proj/study/django/quick_django $ sudo /usr/sbin/apachectl stop

なお、httpd.confの修正などをして再起動する場合は sudo /usr/sbin/apachectl restart を叩けば良い。

ApacheとDjangoの連携

mod_wsgiの導入

さて、Apache環境でDjangoアプリを実行するためにmode_wsgiを導入する。まずは mod-wsgi-httpd から入れる。

1(django) 08:29:40 ~/proj/study/django/quick_django $ pip install mod-wsgi-httpd
2Collecting mod-wsgi-httpd
3  Downloading mod_wsgi-httpd-2.4.46.1.tar.gz (13.1 MB)
4     |████████████████████████████████| 13.1 MB 2.6 MB/s
5Using legacy 'setup.py install' for mod-wsgi-httpd, since package 'wheel' is not installed.
6Installing collected packages: mod-wsgi-httpd
7    Running setup.py install for mod-wsgi-httpd ... done
8Successfully installed mod-wsgi-httpd-2.4.46.1
9(django) 08:52:46 ~/proj/study/django/quick_django $

mod-wsgi-httpd の導入は20分以上かかった。途中、ターミナルのタイトルバー(?)の表示が目まぐるしく変わり、何か動いているようではあるものの、無限ループに陥っていないかとも勘ぐってしまったが、無事に成功した模様。

続けて mod_wsgi を入れる。

1(django) 08:52:46 ~/proj/study/django/quick_django $ pip install mod_wsgi
2Collecting mod_wsgi
3  Using cached mod_wsgi-4.7.1.tar.gz (498 kB)
4Using legacy 'setup.py install' for mod-wsgi, since package 'wheel' is not installed.
5Installing collected packages: mod-wsgi
6    Running setup.py install for mod-wsgi ... done
7Successfully installed mod-wsgi-4.7.1
8(django) 08:55:08 ~/proj/study/django/quick_django $

httpd.confの変更

httpd.confを変更する。まずは格納場所を確認するため、httpd -Vをたたく。

 1(django) 07:58:28 ~/proj/study/django/quick_django $ httpd -V
 2Server version: Apache/2.4.46 (Unix)
 3Server built:   Jan 16 2021 08:19:04
 4Server's Module Magic Number: 20120211:93
 5Server loaded:  APR 1.7.0, APR-UTIL 1.6.1
 6Compiled using: APR 1.7.0, APR-UTIL 1.6.1
 7Architecture:   64-bit
 8Server MPM:     prefork
 9  threaded:     no
10    forked:     yes (variable process count)
11Server compiled with....
12 -D APR_HAS_SENDFILE
13 -D APR_HAS_MMAP
14 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
15 -D APR_USE_SYSVSEM_SERIALIZE
16 -D APR_USE_PTHREAD_SERIALIZE
17 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
18 -D APR_HAS_OTHER_CHILD
19 -D AP_HAVE_RELIABLE_PIPED_LOGS
20 -D DYNAMIC_MODULE_LIMIT=256
21 -D HTTPD_ROOT="/usr/local/Cellar/httpd/2.4.46_2"
22 -D SUEXEC_BIN="/usr/local/opt/httpd/bin/suexec"
23 -D DEFAULT_PIDLOG="/usr/local/var/run/httpd/httpd.pid"
24 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
25 -D DEFAULT_ERRORLOG="logs/error_log"
26 -D AP_TYPES_CONFIG_FILE="/usr/local/etc/httpd/mime.types"
27 -D SERVER_CONFIG_FILE="/usr/local/etc/httpd/httpd.conf"
28(django) 08:19:20 ~/proj/study/django/quick_django $

一番下にある-D SERVER_CONFIG_FILEの右側のパスがhttpd.confの場所。
これを開いて編集する。まず220行目付近でコメント化されているServerNameを有効化して、ServerNmae localhost:8080などとする。 localhost:8080は後で初期表示する際に使うURLで、こうしておかないとhttpd起動時に以下メッセージが出力され、初期ページが表示できない。

1AH00557: httpd: apr_sockaddr_info_get() failed for fuku-no-MacBook-Air.local
2AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set the 'ServerName' directive globally to suppress this message

翻訳結果
127.0.0.1を使用して、サーバーの完全修飾ドメイン名を確実に判別できませんでした。 このメッセージを抑制するには、「ServerName」ディレクティブをグローバルに設定します。

続けて末尾に以下を追加する。

1LoadModule wsgi_module /Users/fuku/proj/study/django/lib/python3.9/site-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-darwin.so
2WSGIScriptAlias / /Users/fuku/proj/study/django/quick_django/quick_django/wsgi.py
3WSGIPythonHome /Users/fuku/proj/study/django
4WSGIPythonPath /Users/fuku/proj/study/django/quick_django
5<Directory /Users/fuku/proj/study/django/quick_django/quick_django>
6<Files wsgi.py>
7Require all granted
8</Files>
9</Directory>

一番上のLoadModuleでロードしているmod_wsgiのパスを確認するには、仮想環境トップからfind . -name mod_wsgi* -printを叩いて表示される.soを選択すれば良い。(以下6行目)

1(django) 09:06:44 ~/proj/study/django $ find . -name mod_wsgi* -print
2./bin/mod_wsgi-express
3./bin/mod_wsgi-apxs
4./lib/python3.9/site-packages/mod_wsgi_httpd-2.4.46.1-py3.9.egg-info
5./lib/python3.9/site-packages/mod_wsgi
6./lib/python3.9/site-packages/mod_wsgi/server/mod_wsgi-py39.cpython-39-darwin.so
7./lib/python3.9/site-packages/mod_wsgi_packages
8./lib/python3.9/site-packages/mod_wsgi-4.7.1-py3.9.egg-info
9(django) 09:07:23 ~/proj/study/django $

WSGIPythonHomeは、djangoプロジェクトを導入している仮想環境のパスを指定。
WSGIPythonPathは、プロジェクトのパスを指定。

この辺のパス設定をミスると、ブラウザ表示で「Internal Server Error」となったりして苦慮することになる。スペルミスなどにも注意。エラー時はエラーログも確認すること。エラーログファイルはhttpd.conf内のErrorLogで指定されているパスにある。
こちらのteratailの記事Django公式サイトも適宜参照のこと。

Django初期ページの表示確認

ブラウザよりlocalhost:8080を指定して、下図のような初期ページが表示されることを確認する。
エラー時はエラーログを確認すること。