Django2 View(ビュー)の構成パターン

# 前提
初心者向け。実践では大体こんな理解が良いかもという説明です。

# 環境
- Windows 10
- Python 3.7.x
- Django 2.2.x

# まずはView(ビュー)の初期構成を確認する
Djangoでは、はじめに次のコマンドでプロジェクトとアプリのひな形を作ります。

```console:
> django-admin startproject some_project
> cd some_project
> python manage.py startapp some_app
```

するとフォルダーの構成は以下になります。

```console:
> tree /f some_project
C:\＊＊＊\SOME_PROJECT
│  manage.py
│
├─some_app
│  │  admin.py
│  │  apps.py
│  │  models.py
│  │  tests.py
│  │  views.py # <= 初期のView(ビュー)は1ファイル構成
│  │  __init__.py
│  │
│  └─migrations
│          __init__.py
│
└─some_project
    │  settings.py
    │  urls.py
    │  wsgi.py
    │  __init__.py
    │
    └─__pycache__
            settings.cpython-37.pyc
            __init__.cpython-37.pyc
```
上記のとおり、アプリ作成時のView(ビュー)は views.py というファイル１つで構成されています。

ちょっと試してみるだけなら、そのままでも問題ありませんが、
実案件では、初動に少し手間がかかっても、
メンテナンスのしやすさを優先した構成にするのが良いです。

# View(ビュー)の構成パターン
View(ビュー)はPythonの機構を利用することで構成を変更できます。
どのような観点で構成を考えられるか、おすすめも交えて簡単に説明します。

##関数ベース / クラスベース
プロジェクトで既定クラスを使いたい場合もあるので、クラスベースがおすすめです。

##ファイルのまま / パッケージ化する
複数人で１つのファイルを扱うのは面倒なので、パッケージ化するのがおすすめです。

##\_\_init\_\_.py で import する / しない
パッケージ化する場合、\_\_init\_\_.py で import するのがおすすめです。
ビューを import するのは urls.py ぐらいなので、
マストではないですが呼び出す側からすると

```Python:
from some_app.views.category.sub_category. import SomeView
```
よりも

```Python:
from some_app.views import SomeView
```
のほうが、パッケージ配下の構成を意識させないので優しいです。

##1ファイル1クラス / 複数クラス
どちらか一方が良いということはないですが、 
ルールを決めるのが良いと思います。

例えば

- CRUD機能は１ファイルに１クラスで定義する
- 共通のデータを扱うCRUD機能は１ファイルにまとめて定義する
- 共通のデータを扱うAjax用の機能は１ファイルにまとめて定義する

といったように。
ルールを決めるときには、以下のような事を考慮すると良いです。

- 画面を見たとき、関連するソースコードを想像・検索しやすいか？
- エディターで編集するときに面倒にならないか？
- 複数人で同じファイルを編集する頻度が高くないか？

##ジェネリックビューを使う / 使わない
ちょっと極端かもしれませんが、以下がおすすめです。

**一覧画面**
ListView (django.views.generic.ListView)
**その他**
View (django.views.View)

ListViewがおすすめなのはページネーション機能を利用できるからです。
その他のジェネリックビューの使用は特段おすすめはしません。

語りだすと色々ありますが、簡単には以下の理由によります。
・ソースコードを読み込むはめになる => 時間がかかる
・それに見合うメリットが得られない => 複雑になる・デバッグしにくくなる

また、Djangoには Model(QuerySet) / Form という、
学習コストが必要だけど便利な機能があります。

ジェネリックビューの理解よりも、
断然それらに学習コストを使うことをおすすめします。

一例ですが、
CreateView (django.views.generic) は以下の継承関係になっています。
※ 太字はクラス名、.xxx() は関数、.xxx は変数です。

- **CreateView**  
  .template_name_suffix
    - **SingleObjectTemplateResponseMixin**  
      .template_name_field  
      .template_name_suffix  
      .get_template_names()  
        - **TemplateResponseMixin**
          .template_name  
          .template_engine  
          .response_class  
          .content_type  
          .render_to_response()  
          .get_template_names()  
    - **BaseCreateView**  
      .get()  
      .post()  
        - **ModelFormMixin**  
          .fields  
          .get_form_class()  
          .get_form_kwargs()  
          .get_success_url()  
          .form_valid()  
            - **FormMixin**  
              .initial  
              .form_class  
              .success_url  
              .prefix  
              .get_initial()  
              .get_prefix()  
              .get_form_class()  
              .get_form()  
              .get_form_kwargs()  
              .get_success_url()  
              .form_valid()  
              .form_invalid()  
              .get_context_data() 
                - **ContextMixin**  
                  .extra_context  
                  .get_context_data()
            - **SingleObjectMixin**  
            .model  
            .queryset  
            .slug_field  
            .context_object_name  
            .slug_url_kwarg  
            .pk_url_kwarg  
            .query_pk_and_slug  
            .get_object()  
            .get_queryset()  
            .get_slug_field()  
            .get_context_object_name()  
            .get_context_data()  
                - **ContextMixin**  
                .extra_context  
                .get_context_data()  
        - **ProcessFormView**  
          .get()  
          .post()  
          .put()  
            - **View** ← *基本、必要なものはこれだけ！* 

以上です。