Index ソフト・ハード Djangoタスク | Djangoの構成・方式 |
機能・要件 構成・方式 仮想環境 プロジェクト アプリケーション 設定ディレクトリ 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)や説明(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
|
All Rights Reserved. Copyright (C) ITCL |