機能・要件 
 構成・方式 
    仮想環境
    プロジェクト
    アプリケーション
    設定ディレクトリ
    settings.py
    開発用サーバ
    モデル
    migration F
    M管理テーブル
    データの取得
    View
    テンプレート
    テンプレートタグ
    staticファイル
    URLconf
    フォーム
    javascript
    メール送信
    画像アップロード
    匿名セッション
    Cookie
    NEWラベル
    独自ユーザ
    認証

    MVT
    メリット
    方式・動作
    GETとPOST
    関数
    サイトマップ
 タスク 
 導入 
 sampleなど
 仮想環境
 ・venv のディレクトリ
 ・参考

 プロジェクト
 ・プロジェクト
制作するWEBアプリ全体
特定のウェブサイトの構成とAPのコレクション
プロジェクト作成例
 ・セキュリティ上、PythonコードをWebサーバーのドキュメントルート下に置かない。
 ・プロジェクト名には組込みのPythonモジュールやDjangoのコンポーネント名などを使わない。
 ・プロジェクトを置きたい場所に移動して作成
 ・生成されたプロジェクトのディレクトリ構成
project01
  |----config        設定ディレクトリ
     |----__init__.py   PythonPKGであることをPythonに知らせる空ファイル
     |----asgi.py     ASGI互換Webサーバーのエントリポイント
     |----settings.py   Djangoプロジェクトの設定ファイル
     |----urls.py     URLディスパッチャ
     |----wsgi.py     WSGI互換Webサーバーのエントリーポイント
  |----manage.py     Djangoプロジェクトの操作を行うコマンドラインユーティリティ

 設定ディレクトリ  (settings.py、wsgi.pyのあるディレクトリ)
 ・プロジェクト作成時の場合
$ mkdir "project名"
$ cd "project名"
$ django-admin startproject config . (第2引数はドット)
 ・プロジェクトの作成後なら
ディレクトリ名を手動でconfigに修正し設定ファイルの内容を変更

 config/settings.py
 ・設定例
 ・デフォルト値 (~/venv/lib/python3.6/site-packages/django/conf/global_settings.py)

 アプリケーション(AP)作成  (トップレベルモジュールとしてインポートする場合、 参考
 ・ウェブログ、データベース、小規模アプリなど、何かを行うWebAP
 ・APは複数のプロジェクトに存在できる。
 ・APはPythonパス上のどこにでも置くことができる。
 ・プロジェクトのmanage.pyファイルと同じディレクトリに作成
 ・アプリを追加していくと、都度フォルダが出来る。
 ・機能の管理を考慮しながら、見通しも考慮し、ディレクトリのネストも考える。
 ・アプリケーションのディレクトリ構成

 開発用サーバ
 ・仮想環境で実施
 ・プロジェクトディレクトリに移動
 ・(venv)$ python3 manage.py runserver
 ・起動中
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
February 02, 2022 - 16:14:35
Django version 3.2.10, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

 モデル  (sample
 ・model.py内のクラス定義  (参考
データベースのレイアウトと、それに付随するメタデータ
各モデルを一つのクラス(各クラス)で表現
各モデルとも django.db.models.Model のサブクラス
各クラスのプロパティはモデルフィールドで規定
プロパティ : クラスのメンバで変数のように参照できる関数
@property
def プロパティ名(self):
pass
各クラスには複数のクラス変数がある。
個々のクラス変数はモデルのデータベースフィールドを表現している。
 ・モデルフィールドの種類
データ型
リレーションに関する情報
デフォルト値
nullの許容など
null : データベース上でNULLを許容するかどうか
blank : ユーザーが入力項目として必須項目にするかどうか
 ・IDの自動生成
明記しない場合は自動生成
 ・マネージャー
各モデルに関する操作に関わる処理をマネージャーに追加
ビューからはその処理を呼び出し、モデルに作用する。
モデルが担うビジネスロジックの処理をモデルで出来る。
 ・利用されるUserモデル
既存のUserモデルを拡張して用いる。
プロキシモデル
OneToOneField
カスタムのUserモデルを作成し、置き換えて用いる。
AbstractUser
AbstractBaseUser
username以外で認証したい場合などに利用できる。
 ・利用されるUserモデル
既存のUserモデルを拡張して用いる。

 マイグレーションファイル
 ・model.pyの内容をDBに反映するための中間ファイル
マイグレーションの実行(migrate)で出されるSQL
 ・makemigrationsコマンドで作成
 ・初回データと一連の差分データで構成
 ・マイグレーションの実行(migrate)で出されるSQL
polls/migrations/0001_initial.py

 マイグレーション管理テーブル
 ・初回マイグレーション実行時、DBに「django_migrations」テーブルが作成される。
 ・マイグレーションファイルの適用分を管理する。
 ・showmigrationsで結果などを表示

 データの取得
 ・クエリセットを生成して返す関数
 ・クエリセット以外を返す関数

 View  (MVT_View views.py)
 ・表示する情報を用意してテンプレートに変数を渡す。
関数ベースとクラスベースのビューがある。
viewで渡した変数をテンプレート内で展開(HTMLの一部に)する。
テンプレート内で展開
 ・ショートカットを使用
テンプレートをロードしてコンテキストに値を入れ、
テンプレートをレンダリングした結果を HttpResponse オブジェクトで返す。
render() 関数
get_object_or_404() 関数
 ・urls.py の urlpatterns に追加
path() コールを追加して、新しいviewを APのurlsモジュールに追加
 ・コンテキスト(辞書型のデータ)
テンプレート変数名をPythonオブジェクトにマッピングする辞書

 関数ベースビュー と クラスベースビュー
 ・関数ベースビューの views.py  (sample(topic_create)
 ・クラスベースビューの views.py  (sample(TopicCreateView)
Get と Post を関数に分けて表現できる。  (sample
 ・urls.py の比較  (sample
クラスベースビューの場合、クラス名の後に as_view() が付く。

 テンプレート  機能
 ・templates ディレクトリからテンプレートを探す。
 ・アプリケーションディレクトリ以下の templates ディレクトリを探す場合
settings.py の TEMPLATES では、「 'APP_DIRS': True, 」
INSTALLED_APPS のそれぞれの templates サブディレクトリを検索する。
 ・各APのテンプレートを一括して管理、を選ぶ場合
プロジェクト配下に templates ディレクトリを置く。
settings.py → TEMPLATES
'DIRS': [], → 'DIRS': [os.path.join(BASE_DIR, 'templates')],
import os
 ・テンプレートを拡張  (sample
base.htmlコンテンツ部分を追加
{% extends 'app/base.html' %}
ExtendsNode:はテンプレートの最初のタグの必要がある。
 ・ページネーション (ページング)
Paginatorクラスを用いてページを複数に分ける。
view.py
Django.core.paginatorモジュール
class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)

 テンプレートタグ
 ・viewから渡された変数をテンプレート内で展開する。
{{ 変数名 }}
 ・テンプレート上で、予め決めたルールでレンダリングできるテンプレートタグ
{% タグ名 %}
{% for item in items %} 、for でループする
{% if 条件 %} <p>条件は真です</p> {% endif %}、条件分岐(if)
{% include "other_template" %}、別のテンプレートを挿入
{% extends "骨格になるファイル名" %}、ファイルの先頭に記述
{% block ブロック名 %}と{% endblock %}
 ・参考

 staticファイル  (画像、CSS、JavaScript)
 ・本番環境での一般的なWebアプリケーションの静的ファイルの配置
静的ファイルはWebサーバのドキュメントルート下
ソースコードや実行ファイルはホームディレクトリ
 ・実際はキャッシュや圧縮技術を駆使してWebサーバよりも高速に静的ファイルの配信
CDNの利用など
 ・開発時は静的ファイルとプログラムが一緒の場所が便利
staticファイルのディレクトリはAPのディレクトリごとに作る。
AP毎のstaticディレクトリを指定ディレクトリに集約コピーする。
collectstatic 機能で集約
 ・本番では集約されたディレクトリからstaticファイルを配信
 ・開発と本番は設定「DEBUG」で切り替え
 ・settings.py での staticファイルに関する設定項目
STATIC_ROOT
collectstatic がデプロイメント用の静的ファイルを収集するディレクトリへの絶対パス
/var/www/example.com/static/ (例、最初は空)
STATIC_URL STATIC_ROOTにある静的ファイルを参照するときに使用するURL
"static/" or "http://static.example.com/" (例)
STATICFILES_DIRS 追加のファイルディレクトリへのフルパスを含む文字列のリスト
STATICFILES_DIRS = [
]
STATICFILES_STORAGE  クラウドやCDN利用時に、利用するサービスのAPIを指定
STATICFILES_FINDERS  STATICFILES_STORAGE を指定する時に指定が必要
 ・static ディレクトリの作成
各APディレクトリの直下
staticディレクトリの直下にAP名でディレクトリを作成
集約時に区別できる。
その下に、css、js などのディレクトリを好みで作成し、ファイルを配置
 ・テンプレートへの記述 (現行での推奨方法)
{% load static %}
<img src="{% static "myapp/image.jpg" %}" alt="MyImage"/>
 ・対象のstaticファイルが今有効なのかどうかを確認  (manage.py findstatic)
(venv) [xxxx@xxxx venv]python manage.py help findstatic
(venv) [xxxx@xxxx venv]python manage.py findstatic .
(venv) [xxxx@xxxx venv]python manage.py findstatic myapp/a.png  (パス名)
適当な一時ディレクトリを作成し、collectstatic を実行してみるのも有効
 ・本番環境へのデプロイ  (静的ファイルをすでにサイトを配信している同じサーバから配信)
Webサーバ の設定例  ( /usr/local/www/mysite/static/ の場合)
settings.py の設定例
STATIC_ROOT に置かれたファイルを STATIC_URL から配信
サーバ側で collectstatic を実行
すべての静的ファイルを STATIC_ROOT で設定したディレクトリに集める。
(開発でも同様の方式を採用する場合は、変更の都度行う。)
(venv) [xxxx@xxxx venv]python manage.py collectstatic
参考

 URLconf (urls.py)  sample
 ・Djangoは、どのモジュールをルートURLconfとして使うか決定
通常、この値は ROOT_URLCONF(settings.py 内) に設定されている。
config.urls
HttpRequestオブジェクトにurlconfという属性が設定されている場合は別
その値をROOT_URLCONFの代わりに使用する。
 ・URLのマッパー(urlpatterns)
ルート(特定のURLパターン) と対応するビュー関数のマッピングのリストを定義
urlpatternsオブジェクトはpath()re_path()関数のリスト
1つ目の引数(route、必須)は、一致させたいルート(パターン)
2つ目の引数(view、必須)は、パターンに一致したときに呼び出される別の関数
3つ目の引数(kwargs)は、任意のキーワード引数を辞書として対象のビューに渡せる。
4つ目の引数(name)は、URLに名前付けをするとDjango のどこからでも参照できる。
 ・include()関数 (他のURLconfへの参照)
include() 遭遇で、そのポイントまでに一致した URL の部分を切り落とす。
次の処理のために残りの文字列をインクルードされたURLconfへ渡す。
 ・URLディスパッチャ  (割り込み処理)
URLマッパーは、URLに基づき、HTTPリクエストを適切なビューにリダイレクトする。
URL内の特定のパターンの文字列などを照合し、データとしてビュー関数に渡せる。
MVCではController

 フォーム  sample
 ・CreateView や UpdateView は他の汎用ビューと異なり、フォームを作成する。
 ・フォーム機能を具現化するFormクラス
ModelFormはFormを継承したクラス
 ・Formクラス
 ・ModelFormクラス
モデルドリブンなWebAP用
fields=[ ] で指定
 ・views.pyなどのプログラム上でform.{フィールド名}で各フィールドにアクセスできる。
 ・forでフィールドをテンプレートテンプレートタグ)に取り出す(例)。  (sample
{{ form.non_field_errors }}  (特定のフィールドに紐づかないエラーを表示)
{% for field in form %}
<div class="field">
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}
<span class="helptext">{{ field.help_text }}</span>
{% endif %}
{{ field.errors }}
</div>
{% endfor %}
 ・フォームの各フィールド form.{フィールド名} の属性
     errors エラーメッセージの集合
field フォームクラスのプロパティ
help_text 説明
html_name インプットタグの name 要素の値
id_for_label ラベルタグ用のid
label ラベル用のテキスト
label_tag ラベルの HTML タグ
value インプットタグ用の value 要素の値
 ・テスト用などで、・テンプレートに一括で取り出す。
一括で取り出す(エラー(errors)や説明(help_text)も全て表示)。
{{ form.as_p }}  (各入力欄をp要素で囲む。)
table要素を利用
{{ form.as_table }}  (各入力欄を<table>で囲む。)
table要素を利用
{{ form.as_ul }}  (各入力欄を<ul>で囲む。)
 ・参考

 javascript
 ・Ajax の使用

 メール送信
 ・バックエンド
SMTP
コンソール
ファイル
インメモリー
django.core.mail モジュールの内にメッセージを保持
 ・複数のメールを送信
 ・参考

 画像アップロード
 ・

 匿名セッション
 ・一般的なセッションの使用
会員制のサイトなどでユーザー情報を保持しておく際によく用いる。
 ・Djangoのセッション
セッションはブラウザを閉じても有効期限まで生き続ける永続的なもの
(ブラウザを閉じても切れない。)
完全にクッキーベース
 ・Djangoのセッションを切るには
意図的に削除する。
有効期限(標準設定では2週間)が来て削除
ブラウザを閉じたらセッションも切れるようにも設定する。
 ・参考

 Cookie
 ・クッキーはユーザーサイドでデータの操作が可能
クッキーが盗難にあう可能性があることを考慮する。
セキュリティ上、重要なデータや個人情報などを保存しない。
 ・ページを跨ぐ情報の一時的な保管場所として利用する。

 現在時刻との差分を計算したNEWラベル
 ・

 ユーザーカスタマイズ  (独自ユーザ 2種類の方法)
 ・既存のユーザモデルの拡張
プロフィールモデルなどをユーザIDとリレーションさせるなど
 ・独自のユーザモデルを構築  (さらに2種類の方法)
AbstructUser を継承したユーザモデルを使用する方法
AbstructBaseUser を継承したユーザーモデルを構築する方法

 認証
 ・djangoの認証は認証用のバックエンドで行う。
settings.py の AUTHENTICATION_BACKENDS に設定 (デフォルト
バックエンドは、配列として追加出来る。
 ・django.contrib.auth を用いた認証の流れ
django.contrib.auth.authenticate関数を呼び出し
設定されたバックエンドのauthenticate関数を順次呼び出し
認証に成功すれば、認証されたユーザーを返す。

 Model View Template(MVT)アーキテクチャ
 ・Model (モデル
アプリケーションのデータ構造を定義
データベース内のレコードの追加、変更、削除及び、照会
データとロジック(MVCでもModel)
 ・View
HTTPリクエストを受け取り、HTTPレスポンスを返すリクエストハンドラ関数
又は例外の送出(Http404など)
DjangoのAPで特定の機能を提供するWebペー ジの型 (type)
Webページとコンテンツを提供する。
各リソースを処理する別々のビュー関数を作成する。
メンテナンスが容易
各々のテンプレートを持つ。
どの様なデータを見せるか(What、MVCでのView)
 ・Template
テンプレートの名前空間
ファイルの構造やレイアウト(HTMLページなど)を定義するテキストファイル
HTMLである必要はない。
データの見せ方(How、MVCでのView)

 DjangoのMVTアーキテクチャのメリット
 ・ユーザー入力を受け入れる部分がフレームワーク自体によって処理される。
 ・モデル、ビュー、テンプレートの様々なコンポーネントが疎結合されている。
他の部分に影響を与えることなく独立して変更できる。
 ・Model View Template は、互いに切り離して利用できる。

 方式・動作
 ・ブラウザがサーバーにリクエストを送る。
リクエストを送るときに使える method の種類は GETとPOST (他にPUTなど)
 ・Djangoは、Pythonモジュール(urls.py)をロードして、(URLマッパー)を探す。
urlpatternsという名前の変数
 ・URLディスパッチャがユーザーリクエストとパラメーターを受信
指定されたパターンと一致するURLを持つHTTPリクエストが受信
 ・Djangoフレームワークは正規表現を介してURLを照合
 ・処理のために対応する ビュー に転送
関連するビュー関数やクラスメソッドが呼び出され、リクエストを渡す。
1つのURLのページ要求を別のビュー処理に分散
 ・ビューはモデルを呼び出してデータを処理
モデルを介して要求を満たすために必要なデータにアクセス
 ・ビューはレスポンスのフォーマットをテンプレートに委任
テンプレートを呼び出してブラウザーに戻る。

 GETとPOST
 ・POSTはブラウザ上で何らかの情報をサーバーに送る場面で使用
問い合わせフォームやユーザー登録など
htmlファイルの formタグで method を指定することもできる。
 ・例、当該viewで、method が POSTのときに、受け取ったデータをメールとして送信する場合
ある人が問い合わせフォームにアクセス
この時は method は GET で、メールを送るという機能は実行されない。
この人が必要事項を入力して「送信」ボタンを押すと同じ view が呼び出されるようにする。
「送信」ボタンを押下の場合は method が POST で、view の内部の処理でメールを送信

 関数
 ・render() (django.shortcuts)
テンプレートを指定のコンテキストでレンダリング、そのHttpResponseオブジェクトを返す。
第1引数 request オブジェクト
第2引数 テンプレート名
第3引数 (任意)辞書を受け取る。
 ・get_object_or_404() (django.shortcuts)
任意の数のキーワード引数を取り、モデルのマネージャのget()関数に渡す。
オブジェクトが存在しない場合はHttp404を発生
第1引数 Django モデル
 ・get_list_or_404() (django.shortcuts)

 サイトマップ
 ・Sitemap継承クラス(例)    thread/sitemaps.py     from django.contrib.sitemaps import Sitemap     from django.shortcuts import resolve_url     from . models import Topic, Category     class TopicSitemap(Sitemap):      priority = 0.5 # ページの重要度(0〜1)      changefreq = 'never' # ページの更新頻度(他、always など)      def items(self):      return Topic.objects.all()      def location(self, obj):      return resolve_url('thread:topic', pk=obj.id)     class CategorySitemap(Sitemap):      priority = 0.5      changefreq = 'never'      def items(self):      return Category.objects.all()      def location(self, obj):      return resolve_url('thread:category', url_code=obj.url_code)    base/sitemaps.py     from django.contrib.sitemaps import Sitemap     from django.shortcuts import resolve_url     class BaseSitemap(Sitemap):      def items(self):      items = [      'base:top',      'base:policy',      'base:terms',      ]      return items      def location(self, obj):      return resolve_url(obj)      def changefreq(self, obj):      if obj == 'base:top':      return 'always'      return 'never'      def priority(self, obj):      if obj == 'base:top':      return 0.8      return 0.1