※本記事は個人の自己研鑽として取り組んだ内容であり、所属組織の公式見解や業務事例ではありません。
概要
- 日頃、Javaに触れている筆者が、DjangoでWebアプリを作成する一連の学習で得た気づきを共有できたらと考えています...
- 筆者の理解不足、環境やバージョンにより挙動が変わる場合などがあり得るかもしれません。併せて公式情報もご確認ください...
前提・背景
-
Java:ある程度読み書きできます...
-
Pythonはあまりわからないです (推測や調べつつ解読できる程度です...)。
-
現状の私のPython言語仕様の世界観:
- インデントが文法として意味を持ち、Javaでいう
{ }を表現している。
- Javaはスタティックな型付けなのに対し、Pythonは動的型付け。
https://docs.oracle.com/javase/specs/jls/se24/html/jls-4.html
https://typing.python.org/en/latest/spec/concepts.html#static-dynamic-and-gradual-typing
- Javaでは継承での基底クラスは常に1つだが、Pythonは多重継承ができるので複数の基底クラスを持てる。
- Pythonは関数も値として扱え変数に入れられる。JavaでもFunctional Interfaceを使い似たことはできるが、インタフェースでの単一な抽象メソッドに処理を乗せることで実現している。
https://docs.python.org/3/reference/compound_stmts.html#function-definitions
- コード文末の
;がいらない。ただし複数文を1行で書くときは区切りとして使ってもいい。
https://docs.python.org/3/reference/simple_stmts.html#simple-statements
- インデントが文法として意味を持ち、Javaでいう
Djangoって何て読むのだろうか...
「ジャンゴ」と読むと認識しました。
https://docs.djangoproject.com/en/6.0/faq/general/#what-does-django-mean-and-how-do-you-pronounce-it
Pythonの導入は何をやればよいのだろうか...
Python環境は様々あるようですが、今回は個人的な学習用途だったためAnacondaを導入しました。
ただ、Anacondaは商用利用が条件によっては有償になっている模様のため、業務で使う場合は留意が必要と認識しました。
pipって何?
Javaでいうmvn (の依存関係を解決して取得) に似たしくみと理解しました。Pythonでのいわゆるパッケージ導入のしくみで、pip installで、Pythonの様々なライブラリを導入できると認識しました。
ただし
mvnはビルドツールですが、pipはパッケージインストーラであり、役割自体が違うと認識しました。
いろいろ始める前にまずはpipenvで仮想環境を作るのはわかったが、一方で仮想環境を作る標準機構venvもある...何が違うのだろうか
- PCにインストールしたPython環境自体を汚さないように、開発を始める一番初めに、まずは個別に仮想環境を作るものと認識しました。
-
venvは仮想環境を作る手段で、仮想環境ごとにpipでのライブラリ導入状況が分離されると認識しました。
-
pipenvは、venvとは別物な仮想環境 + pipで何を入れたかのリスト(lockファイル)を設けることで、誰でも同じ環境を再現でき、いわゆるJavaでいうpom.xmlの依存管理に近い発想と認識しました。
pipenvやDjangoってどうやって入れるのだろうか...
- pipenvは、
pip installコマンド経由で導入できました。
- pipenvを入れた後、
pipenv install djangoを実行することで、仮想環境にDjangoを導入できました。
https://pipenv.pypa.io/en/latest/virtualenv.html#how-pipenv-uses-virtual-environments
https://pipenv.pypa.io/en/latest/installation.html#next-steps
- PythonとDjangoとで、対応バージョンの組み合わせがあるので留意が必要でした。
https://docs.djangoproject.com/en/6.0/releases/6.0#python-compatibility
https://docs.djangoproject.com/en/6.0/releases/5.2#python-compatibility
Visual Studio Code (VS Code)で開発するつもりだが、拡張機能は何を入れればいいのだろうか...必要な最小限にしたい。
- Microsoft公式のPython拡張機能があり導入しました。導入するとPython、Python Debugger、Python Environments、Pylanceがセットで導入されました。
https://marketplace.visualstudio.com/items?itemName=ms-python.python
VS Codeで拡張機能を入れたのに、メソッドなどのコンテンツアシストが出ないし、記述したPythonコードの構文が解釈されない...
- VS Codeのコマンドパレットから
Python: Select Interpreterを使い設定すると認識しました。
https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment
Djangoプロジェクトを作成するためにコマンド実行が必要だが、pipenvの仮想環境内でコマンドを実行する方法がわからない...
pipenv run django-admin startproject config .
https://docs.djangoproject.com/en/6.0/ref/django-admin#startproject
-
pipenv runを先頭に付ける必要があると認識しました。
一方、
pipenv shellで入ると、そのままコマンドが使える模様です。
https://pipenv.pypa.io/en/latest/virtualenv.html#activating-the-virtual-environment
manage.pyって何?
- Djangoで様々な処理を行うときに入り口となるコマンドを提供するものと認識しました。
https://docs.djangoproject.com/en/6.0/ref/django-admin#django-admin-and-manage-py
- pipenv内でのコマンド実行なので、
pipenv runに加え、pythonをつける必要があると認識しました。 -
pipenv run python manage.py <<manage.pyが提供する各種コマンド>>というコマンドになります。
例えば、以下をよく使いました。
サーバー起動:pipenv run python manage.py runserver
https://docs.djangoproject.com/en/6.0/intro/tutorial01#the-development-server
Djangoでの「アプリケーション」という用語は、どうやら普段使っているアプリケーションとは違う意味のようだ...
- Djangoでは、機能単位のことを「アプリケーション」と呼称すると認識しました。
https://docs.djangoproject.com/ja/6.0/ref/applications/#projects-and-applications
- アプリケーションは、
manage.pyで作成コマンドが提供されています。 -
pipenv run python manage.py startapp <<機能単位の任意の名称>>で作成ができます。
https://docs.djangoproject.com/ja/6.0/intro/tutorial01/#creating-the-polls-app
- 実行すると、フォルダと.pyファイルの一式が作成されました。
- コマンドを実行するだけでなく、一式が作成された後は、
settings.py内のINSTALLED_APPSにアプリケーションフォルダ名を追記する必要がありました。
https://docs.djangoproject.com/ja/6.0/ref/applications/#projects-and-applications
もし、追記を忘れていると
makemigrationsしても認識されず、留意が必要でした。
https://docs.djangoproject.com/en/6.0/intro/tutorial02#database-setup
結局Djangoのプロジェクトを作って、manage.pyでstartappをしてみたが、いろんな.pyが作られて何をどうすればいいかが、わからない...
Java (Spring Boot)でいうと、イメージ優先で以下の対応になると認識しました。
| Django | Java (Spring Boot) | 何を担うか |
|---|---|---|
| models.py | JPAのEntityとRepository(DAO) | データベースの操作・データ取得・永続化 |
| templateフォルダ配下のhtml | Thymeleaf | フロント側 (画面) |
| urls.py | Controllerアノテーションを付与したクラスで使うHTTPメソッド系の各種アノテーション (@RequestMapping、@GetMapping、@PostMappingなど) |
ルーティングと処理のマッピング |
| views.py | Controllerアノテーションを付与したクラスでの、HTTPメソッド系のアノテーションを付与した「メソッドの処理本体」の部分 | リクエストを受け取り、処理を行い、レスポンスを返す (画面的なViewではないと解釈しました...) |
| settings.py | application.properties | プロジェクト全体に関する設定(言語設定など) |
| forms.py | 任意のDTO・Bean | フロント側 (画面)から受け取ったデータの保持、バリデーション |
https://docs.djangoproject.com/en/6.0/topics/db/models#module-django.db.models
https://docs.djangoproject.com/en/6.0/topics/http/urls#url-namespaces
https://docs.djangoproject.com/en/6.0/ref/templates/language#the-django-template-language
https://docs.djangoproject.com/en/6.0/topics/http/views#writing-views
https://docs.djangoproject.com/en/6.0/topics/settings#django-settings
https://docs.djangoproject.com/en/6.0/topics/forms#working-with-forms
Djangoでの「マイグレーション」という用語は、どうやら普段見聞きする「旧システムからの移行」とは違う意味のようだ...
- Djangoでは、データベースへの永続化手段が標準で用意されていて、Pythonで記述したクラスをデータベースに反映する一連の手段や操作を「マイグレーション」と呼称すると認識しました。
-
models.Modelを継承したモデルクラスをmodels.pyにて作成することで、SQLなしでも基本的なCRUDが実現できると認識しました。 - JavaでいうとJPA・Entityに相当すると認識しました。
- マイグレーションは、
models.pyに新しいモデルクラスを追加するたびに行うと認識しました。
https://docs.djangoproject.com/en/6.0/topics/migrations#module-django.db.migrations
manage.pyが提供するmakemigrationsコマンドとmigrateコマンドって何が違うのだろうか...
-
makemigrationsコマンドは、models.pyのクラスから新しいマイグレーションファイルを作るまで (まだDBには反映しない)
https://docs.djangoproject.com/en/6.0/ref/django-admin#makemigrations
-
migrateコマンドは、未適用のマイグレーションファイルをDBに適用する。
https://docs.djangoproject.com/en/6.0/ref/django-admin#migrate
- 基本的な順番としては、
models.pyにモデルを記述 ->makemigrationsコマンド ->migrateコマンドとなると認識しました。
Pythonでの「モジュール」、「サブモジュール」、「パッケージ」の概念がわからない...
- モジュールとは importできる単位そのもので、おおむね「.pyファイル自体」のことと理解しました。
- パッケージとは、「配下にモジュールを持っているモジュール」のことと認識し、具体的には「.pyを格納したフォルダ一式」のことと解釈しました。
- サブモジュールとは、パッケージの中にあるモジュールのことと認識しました。
そもそも、.pyにクラスをどう記述するのだろうか。Javaの場合、基本publicなクラスは1ファイルに1つの慣習だが、継承やオーバーライドの書き方も違うようだ。
-
def __init__が実質Javaでのコンストラクタに相当するものと認識しました。
Pythonでは、インスタンス生成
__new__と、初期化__init__が区別されていると認識し、「実質」としました。
https://docs.python.org/3/reference/datamodel.html#basic-customization
- サブクラス側にて、同じメソッド名・シグネチャで定義することで、オーバーライドできると認識しました。
class <<サブクラス名>>(<<基底クラス名>>):
def __init__(self, <<基底クラスと同じ引数シグネチャ>>):
super().__init__(<<基底クラスと同じ引数シグネチャ>>)
<<独自の処理>>
def <<オーバーライドしたいメソッド名>>(<<同じ引数シグネチャ>>):
<<処理を記述>>
- Pythonでは、.pyはモジュールなので、1ファイル内に複数のクラスを定義してもOKと理解しました。
__init__.pyって何?
- パッケージとして実装する際にディレクトリに入れておく.pyと認識しました。
ただし、namespace packageという実装方法を使うと
__init__.pyは不要な模様です...
- パッケージがimportされたときに、暗黙的に実行されるものと認識しました。
- イメージでいうと、パッケージでのコンストラクタ的な立場のものと解釈しました。
https://docs.python.org/3/tutorial/modules.html#importing-from-a-package
import文がJavaと違う... fromとは何を意味しているのだろうか...
以下の2パターンがあると理解しました。
-
from <<完全修飾名>> import <<名称>>: <<完全修飾名>>の中に実在する <<名称>>だけをimportする。 -
import <<完全修飾名>>: javaと同じく、<<完全修飾名>>で指定したものをimportする。 - importしたものを、任意の名称で使いたい場合は、 import文の末尾に
as <<任意の新しい名称>>を付与することででできると認識しました。
https://docs.python.org/3/reference/simple_stmts.html#the-import-statement
サーバーが、manage.pyから起動できることはわかるが、終了時はどうやるのか...
- Ctrl + Cでコマンドをキャンセルすれば起動したサーバーを終了できました。
- サーバー起動した際のターミナルにて、
Quit the server with CTRL-BREAK.と記載がありました。
https://docs.djangoproject.com/en/6.0/intro/tutorial01#the-development-server
Djangoではスーパーユーザーなるものがあるらしい...そして標準で管理画面がついているらしい...
-
manage.pyが提供するcreatesuperuserコマンドを使い、スーパーユーザーが作成できることを理解しました。
https://docs.djangoproject.com/en/6.0/ref/django-admin#createsuperuser
migrateコマンドまでをあらかじめ実行しておく必要があると認識しました。migrateコマンドまでをあらかじめ実行しないで行った場合、no such table: auth_userエラーで失敗しました。
- 管理ユーザー作成後に、
127.0.0.1/adminにアクセスすると、管理画面ログイン画面に到達でき、作成したスーパーユーザーでログインできました。
https://docs.djangoproject.com/en/6.0/intro/tutorial02#start-the-development-server
特にデータベースの設定をしていないが、永続化されているようだ。JavaでのH2 Databaseのようなものが自動で動いているのだろうか...
- Djangoでは、デフォルトでSQLiteを使う設定になっていると認識しました。
https://docs.djangoproject.com/en/6.0/faq/install/#what-are-django-s-prerequisites
https://docs.djangoproject.com/en/6.0/intro/tutorial02#database-setup
- 別のデータベースを使う場合は、
settings.py内のDATABASESの記述を変更する必要があると認識しました。
https://docs.djangoproject.com/en/6.0/topics/db/multi-db#defining-your-databases
データベースの中身を見たい...
-
manage.pyが提供するdbshellコマンドで、SQLiteデータベースの中身を確認できると認識しました。
https://docs.djangoproject.com/en/6.0/ref/django-admin#dbshell
- また、前述の管理画面からも確認できると認識しました。
むすび
- Pythonは、ExcelにてPython in Excelとして、標準で実行環境が用意されたり、LLMがコード実行する際にも使われたりしていて、用途がより広がっていると認識しています。今後もPythonに触れていきたいと考えています...
- 最後までお読みくださり、ありがとうございました!