Django でブラウザからモデルへデータへの読み書きをする

Python

前回の続きです。

Django でモデルをマイグレートする
前回の続きです。ほぼ udemy 「【3日でできる】はじめての Django 入門」の内容の備忘録になります。今回することDjango では、DB のことをモデルと呼ぶらしいです。(個人的にはモデルってドメインロジックとかも含める...

ほぼ udemy 「【3日でできる】はじめての Django 入門」の内容の備忘録になります。

今回やること

以下の図でいう、ブラウザからモデルを経て DB にデータを書き込むところまでやってみます。

Webブラウザルーティング(プロジェクト内)myfirstapp.urlsビュー(index)views.indexアクセス(ページリクエスト)リクエスト先のページを取得該当するページを返すルーティング(postsアプリ内)posts.urlsビューテンプレートファイルindex.htmlテンプレートファイル(html)の読み込みモデルmodels.Postsqlite3

具体的に、 Django のデフォルトで作成される admin ページに、前回作成した Post テーブルにデータを書き込む処理を追加します。

admin ページに Post テーブルを書き込む機能を追加

admin ページを表示してみる

まず、デフォルトで自動生成されている admin ページを表示してみます。
http://127.0.0.1:8000/admin/login/?next=/admin/

ただし、ログインID とかはまだないみたいです。

管理者アカウントを作ってみる

このままでは自動生成とはいえ自分が作ったページにログインすることができないので、管理者アカウントを作ってみます。

(env1) C:¥Users¥hoge¥myfirstapp> python manage.py createsuperuser

すると、以下のようにユーザー名やメールアドレス、パスワードを入力を促されるので、適当に入力する(今回はお試しアプリなので適当ですが、本当にアプリを運営するならちゃんとやったほうがいいです)と管理者アカウント(superuser)が作成できます。

ユーザー名 (leave blank to use 'hoge'): hoge
メールアドレス: hogehoge@sample.com
Password:   # 8文字以上で英数字混在
Password (again):
Superuser created successfully.

admin ページにログインしてみる

上記で作成したアカウントでログインできます。

あらかじめページが作られていますね。グループとかユーザーとか、ちゃんと追加変更ができるみたいです。
Scaffold に近いものがありますね。

Post テーブルに書き込む機能を追加する

この admin ページに Post への書き込みをする機能を追加します。

結構大変なのでは?と思ったのですが、すごく簡単でした。
posts\admin.py 以下のように書くだけです。

# posts\admin.py

from django.contrib import admin

# 同一フォルダ内の models.py にある Post クラスを読み込む
from .models import Post

# admin ページに Post を登録
admin.site.register(Post)

すると、admin ページが以下のように変わります。

実質1行足しただけでビューが変わりました。
C言語上がりの私からすると、けっこう驚きです。(中で何がどうなってるんだろうか・・・??)
上記で Posts の「追加」を押すと、以下のページに遷移します。

これも驚きですが、テーブルの構成を元に自動で画面を生成してくれています。
とりあえず上記の通り項目を適当に埋め、「保存」してみました。

予想通りでしたが、ちゃんと「保存」されており、アプリケーションを立ち上げなおしてもデータが残っていました。
つまり、ちゃんと DB に書き込みができているということです。

1行書くだけで CRUD 操作ができるようになるとは。本当にすごいですね。

一覧にタイトルを表示する

現状では、以下のように一覧表示しても、Post テーブルに何が入っているのかわかりません。

そこで、一覧表示で Post テーブルの title 属性を表示するようにしてみます。

概念的なこと

まず概念的なことですが、一覧に表示されているデータは、Post クラスのオブジェクトということになるみたいです。
つまり Django では、ページ上に表示されているモデル(つまりDBのテーブルクラス)のデータは、C# 的に言うとオブジェクトにマッピングされたインスタンスということです。
どういう風に O/R マッピングしているのか、はたまたそもそもマッピングさえしておらずオブジェクトとして保存しているのか不明ですが、そういうところは完全に隠蔽されているようです。

で、じゃあどうやって一覧にタイトルを表示すればよいかというと、これも C# 的に言うと、「モデルのクラスに ToString() をオーバーライドしてやればよい」ということになります。
クラスに文字列を返す定義を記述してやれば、一覧で表示されるインスタンスもその定義通りに文字列を返してそのまま表示されるということです。

Post クラスに文字列を返すメソッドを追加する

以下のように posts\models.pyPost クラスを変更します。

# import とかは省略

class Post(models.Model):
    title = models.CharField(max_length=100)
    published = models.DateTimeField()
    image = models.ImageField(upload_to='media')
    body = models.TextField()

+   # __str__ という表記で、C# でいうところの ToString() を実装できる
+   # このクラスのオブジェクトを文字列で返すことができるようになる
+   def __str__(self):
+       return self.title

これで、Post クラスのインスタンスは文字列として title を返すようになります。

こうすることで、以下のように一覧に title が表示されるようになりました。

コメント

タイトルとURLをコピーしました