Python(Django) をWindows+IISで動かす

# Windows上のIISでPythonのwebサービスを動かす
Windows7 32bit上で、Pythonのwebサービスを稼働させた。
最初はApache系を使って動かしたかったけれど、うまくできなかった。
IISでやってみたところ、こちらも苦労したものの実現できたので、本番への導入はIISにした。
なお、Apacheの方もできないままだと悔しいので、いずれリベンジを果たしたい。

## IISでPythonによるwebサイト開設
コントロールパネル → 「プログラムと機能」から「Windowsの機能の有効化または無効化」をクリックし、「インターネット　インフォメーション　サービス」に関する項目のチェックをオンにする。すると「プログラムとファイルの検索」で「inetmgr」と入力すればIISマネージャを起動できるようになる。
IISマネージャ上で新しいサイトを作成し、バインドを設定する。アプリケーションプールを「.NET Framework v4」に変更する。ここまでは.NET webアプリと同じ一般的な手順となる。

次にPython（3.6.0）をインストールする。この時、「Add Python X.X to PATH」にチェックを入れること。これを忘れると後の手順でコマンドプロンプトから直接pythonやpipと打てなくなってしまう。

![python.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/b0fe9a9c-c2c5-0e97-feeb-1acf0adb2091.png)

また、インストールは「Costomize installation」を選択し、「Install for all users」にチェックを入れること。

![python2.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/4aba4178-0515-0827-b1e3-bd7d898ef92b.png)

下記に従い、Pythonのハンドラマッピングを追加する。

>Microsoftサポート
[IIS] IIS で Python スクリプトを使用する
https://support.microsoft.com/ja-jp/help/276494/using-python-scripts-with-iis

「ハンドラマッピング」を選択する。
![iis10.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/6d4b1265-8c71-68d9-ef60-78d2ef1ce4c7.png)

「要求パス」に「*.py」と入力し、「実行可能ファイル」にPythonをインストールしたパスを指定する。
![iis11.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/10ab9294-ce4d-d560-6022-dd77b5fe11bf.png)
「実行可能ファイル」は上記のように書いたあと、後ろに『%s %s』を付ける必要がある

以下はPython3.6.3を初期値のままインストールした場合の例。

```
"C:\Program Files\Python36-32\python.exe" %s %s
```

これまでの作業により、webサイトで単純な.pyファイルを開くことが可能になる。

## IISでDjangoを動かす＃1（Python環境側）

最初はDjangoを動かす方法が全然分からなかった。情報を探していてこのサイトを発見して、救われた。

http://thinkami.hatenablog.com/entry/2015/10/26/070118

上記サイトに書かれている通り、手順を進める。

- IIS webサイトのフォルダを作り、その中に移動して仮想環境を作成する。
- Djangoとwfastcgiをインストールする。
- Djangoプロジェクトを作成して、そのフォルダ内へソースをコピーする。
Visual Studioで開発している場合はプロジェクトフォルダ内のappフォルダ、manage.py、プロジェクト名のフォルダ（例ではPlanningServiceフォルダ）を開発環境からコピーする。
- マイグレートをかける。

以下、使用した主なコマンド。

```
pip install virtualenv
virtualenv myenv
myvenv\Script\activate
pip install django==1.11
pip install wfastcgi
django-admin.py startproject planningservice
cd planningservice
python manage.py migrate
```

マイグレートしたら、足りないモジュールが表示されるので、その都度インストールを行っていく。以下の例だとpyodbcが足りないというわけ。

![odbc_error.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/cc8cfb4f-afb8-5385-1a8e-48007b6e217e.png)

そこで以下のコマンドを入力して、pyodbcをインストールすればよい。

```
pip install pyodbc
```

同様にmatplotlib、pil-compat、pandas、seabornなど開発内容に合ったモジュールをインストールする。モジュール不足のエラーが出なくなれば、Python側の準備は整った。

## IISでDjangoを動かす＃2（IIS側）

続いて、IIS側のバインドを整備する。
まずwebサイトの物理パスは、Djangoプロジェクトのフォルダ（manage.pyが存在するフォルダ）まで指定する。
続いて、再び上記サイトに書かれている手順に従う。

- IISにwfastcgiを設定する。

```
%windir%\system32\inetsrv\appcmd unlock config -section:system.webServer/handlers
wfastcgi-enable
```

- web.configを修正する。
今回使用したweb.configはこちら。

```web.config
<configuration>
  <appSettings>
    <add key="WSGI_HANDLER" value="django.core.wsgi.get_wsgi_application()" />
    <add key="PYTHONPATH" value="C:\Product_Mng\web" />
    <add key="DJANGO_SETTINGS_MODULE" value="planningservice.PlanningService.settings" />
  </appSettings>
  <system.webServer>
    <handlers>
        <add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="c:\product_mng\web\env\scripts\python.exe|c:\product_mng\web\env\lib\site-packages\wfastcgi.py" resourceType="Unspecified" />
    </handlers>
  </system.webServer>
</configuration>
```

IISの「Webサイトの参照」からブラウザを開くと、500エラーとなってしまった。
>500.0 Internal Server Error
 エラーコード c0000135

これは、pyファイルを編集する際に既定のプログラムをエディターに設定してしまったため。既定のプログラムをPythonに設定し直してやれば、Djangoによるwebサイトが表示された。ひとまずwebサービスは構築できた。

![nac.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/5e720d86-d545-bd4f-a64e-92af0a63a58a.png)

しかし、CSSが効いていない。ここで原因が分からず、Djangoをダウングレードしてみたり、Anacondaをインストールしてみたりしたが、問題は変わらなかった。問題はDjangoの中にある模様。静的ファイルが足りないことを手掛かりにググってみると、static設定を操作すれば解決しそう。

```
python manage.py collectstatic
```

collectstaticをすると、product_mng\planningservice\static内に静的データが移行された。これらの静的ファイルにアクセスすると404エラーになる。これらのファイルをwebサイトから参照するには、url.pyに記載されていないといけない。

![django22.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/f1f1e347-3858-f5fb-6a6a-5ce22b2550b9.png)

ではどこでそれを設定するかというとDjangoではなく、IISの問題だった。

http://thinkami.hatenablog.com/entry/2015/12/26/215543#URL%E3%81%AE%E8%A8%AD%E5%AE%9A

再び上記ブログに救われた。ありがとうございます。ｍ（＿＿）ｍ
これを書いた方が、他のブログを挙げてとても参考になったと謝辞を述べておられる。
いったい上にはどれだけ上がいることやら。

ブログに記載の通り、IIS全体のweb.configとは別に配信の例外ルールを記載した静的ファイル用のweb.configを作成し、staticフォルダ直下に設置する。

```
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <remove name="Python FastCGI" />
    </handlers>
  </system.webServer>
</configuration>
```
これでCSSが効いた。

![ack.PNG](https://qiita-image-store.s3.amazonaws.com/0/241999/171a29a6-41fe-979e-b5a1-3bb07fd9c9d1.png)

## デプロイ後に静的ファイルを更新するには

CSS等の静的ファイルたちを更新するときは、ファイルを置き換える度に、collectstaticをやってあげないといけない。
例としてCSSを更新するときは、本番環境のstatic\app\content内のファイルを置き換えてから、以下のコマンドを実行する。

```
manage.py collectstatic
```

すると、上書きをするかどうか確認される。上書きを選択したら、上書きされたファイル数と、変更がなかったファイル数が表示される。