【Visual Studio2017】Djangoアプリをherokuにデプロイする際にハマったポイント


##書いてあること
Windows10/Visual Studio2017で作成した簡易なDjangoアプリをherokuにデプロイするまでの試行錯誤です。同環境でハマってる情報があまり見られなかったので、何番煎じか不明ですが書きます。
herokuへのデプロイについては無数に情報ややってみた記事があるにもかかわらず各々が各々の道で詰んでしまうので、そこから抜けた人はみな嬉しくて記事を書いてしまう。

##ハマりポイント概要
+ VisualStudioで生成されるフォルダ構成の不一致
+ template名の指定方法
+ そもそもVisual Studioで行うプロジェクト生成・アプリケーション生成があやしい

##参考手順
[[Django] Heroku デプロイ方法 2018年版](https://qiita.com/okoppe8/items/76cdb202eb15aab566d1 "[Django] Heroku デプロイ方法 2018年版")

結果的にはほぼこちら、およびこちらからのリンク先を参考にして問題なく動作しました。

##デプロイしようとしたアプリ
クラスベースジェネリックビューを使ったごくごく簡単なチャットアプリです。ここでは詳細略。

##ハマりポイント詳細
###1. Visual Studioで生成されるフォルダ構成の不一致
#### ・どこでエラー出たか
herokuリポジトリへのpushがrejectされた。

```cmd.exe
git push heroku master
…略
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'https://git.heroku.com/＜アプリケーション名＞.git' 
…略
```
自分が作業中に他のヒトがgit pushするなどしてしまうと起きるらしいけれど、そんな環境ではない……。

#### ・原因
ここでフォルダ構成を見てみると

```
.
│  SampleApp.pyproj.user
│  SampleApp.sln
│
└─SampleApp
    │  .gitignore
    │  db.sqlite3
    │  manage.py
    │  Procfile
    │  readme.html
    │  requirements.txt
    │  runtime.txt
    │  SampleApp.pyproj
    │  SampleApp.pyproj.user
    │
    ├─app
    │  │  forms.py
    │  │  models.py
    │  │  tests.py
    │  │  urls.py
    │  │  views.py
    │  │  __init__.py
    │  │
    │  ├─migrations
    │  │      __init__.py
    │  │
    │  └─templates
    │      └─app
    │              about.html
    │              ...
    │
    └─SampleApp
            settings.py
            urls.py
            wsgi.py
            __init__.py
```

こんな感じで、.slnもリポジトリに含めるため、ここのルートで git init してた。
そうなると
[公式サポートの Deploying Python and Django Apps on Heroku](https://devcenter.heroku.com/articles/deploying-python#expected-files-for-python "")
>Heroku automatically identifies your app as a Python app if any of the following files are present in its root directory:
>
>+ requirements.txt
>+ setup.py
>+ Pipfile

>If none of these files is present in your app’s root directory, the Python buildpack will fail to identify your application correctly.

の通り、ルートに上記ファイルがなんもないのでDjangoアプリと認識できず失敗する。
だからといってrequirements.txtだけルートに置き直しても、Djangoっぽいフォルダ構造とは見なされないので失敗する。

なんでこうなるのかというと、VSソリューションを作った後、空のソリューションからVSのGUI使ってディレクトリつきでDjangoプロジェクトを作っちゃったから。

#### ・対応
これを解消するだけなら単にSimpleAppフォルダの中身を全部ルートにmoveするだけでいいけど、
後述するように最初からVisual Studioの機能は使わず、ソリューションファイルの階層で

```
django-admin startproject ＜プロジェクト名＞
python manage.py startapp ＜アプリケーション名＞
```

した方が無難。
ともかくこれでこのエラーはなおった。

###2. template名の指定方法
#### ・どこでエラー出たか
無事ビルドが完了した後、トップページへのアクセスでサーバー500エラー。

```
2019-02-02T13:19:59.721011+00:00 heroku[router]: at=info method=GET path= ...略
 dyno=web.1 connect=1ms service=120ms status=500 bytes=234 protocol=https
```
ローカルではやはり動く。

#### ・原因
templates名を、クラスベースジェネリックビューのデフォルトのものにしているとこうなる。
たとえばCreateViewだと

| Model | View | ジェネリックビューの種類 | デフォルトTemplateファイル名 |
|:-:|:-:|:-:|:-:|
| MyModel  | MyView  | CreateView  | MyModel_Form.html  |

のようにtemplates名をつけておくと、ビューの中でtemplate_nameを明示的に指定しなくてもtemplateを参照してくれる。
してくれるはずなんだけどしてくれていないようだ。
  

#### ・対応
いろいろ試したけど最終的にあきらめてtemplate_nameを指定した。
上に書いたフォルダ構成のように、templatesフォルダ内にアプリケーション名フォルダを作るやり方だと

```python:views.py
class FirstView(CreateView):
    model='MyModel'
    template_name='app/MyModel_Form.html'
```

とフォルダまで指定してやらないといけない。

###3. そもそもVisual Studioのプロジェクト生成があやしい
#### ・どこでエラー出たか
上でトップページは表示されたが、POSTしたあとのページ遷移で同じく500エラー。

#### ・原因
いろいろ試したが不明だった。

+ 静的ファイルまわりの設定
+ settings.pyのDIRS[]
+ urls見直し

などしてみたが変わらず。またhttpの通信ログ以外にはエラーも出ない。
ただ遷移先のアドレス直打ちすると表示されたので、やっぱpathの解決がうまくいってないんだろうなと思われた。

#### ・対応
```
django-admin startproject ＜プロジェクト名＞
python manage.py startapp ＜アプリケーション名＞
```
でもろもろを再構築してソリューションに入れ直した。
requirements.txtはとっておいて仮想も入れ直し。
ローカルで動作確認済みのファイルもとっておいて上書き。

これだとVisual StudioからF5でデバッグできなくなったりしたので、まだ知らん挙動がありそうだけど、runserverして動作したのを確認してからデプロイし直したら動いた。ひー。

##結論
VisualStudioくんもうちょっとがんばってくれるといいな。
まだGUIから作るとDjango1系になっちゃうし。