Djangoの機能構成を理解する
MVT(Model・View・Template)というDjangoの機能構成について理解していきます。
モデル・ビュー・テンプレートの役割
- モデル:アプリで扱うデータを保持し、操作する
- ビュー:ユーザーからのリクエストに応じて、モデル・テンプレートを呼び出す
- テンプレート:データの表示形式を記述する
- ルーティング:リクエストを振り分ける
Djangoでデータベースを操作できるツール
- Djangoシェル:Djangoアプリの環境を有効にしたまま、コマンドで操作
- マイグレーション:データベースの操作を一括実行・取り消し
- 管理サイト:Webブラウザで、データベースを操作する
Djangoシェルでデータベースを確認
Djangoシェルを使うと、Djangoアプリの環境を有効にしたまま、Djangoの機能をコマンドで操作できます。
Djangoシェルを起動と終了
$ cd myapp $ python manage.py shell # 起動
※ 終了は「ctrl+d」キー
Djangoシェルの主な操作コマンド
# テキストを入力 In[1]: print('Hello Python') Hello Python # プリント関数を使わずにデータを書くと、そのまま出力する In[2]: 'Hello Python' Out[2]: 'Hello Python' # テーブルの全てのレコードを出力 In[3]: from bbs.models import Article In[4]: Article.objects.all() Out[4]: , , ]> # 指定idのデータを取り出し、カラムを出力 In[5]: article = Article.objects.get(pk=1) # プライマリキーが1のデータを取得 In[6]: article.content Out[6]: 'Hello world' # データを追加する In[6]: article = Article(content='Hello Django') In[7]: article.save() # データを修正する In[8]: article = Article.objects.get(pk=1) In[9]: article.content = 'Good Morning' In[10]: article.save() # データを削除する In[11]: article = Article.objects.get(pk=4) In[12]: article.delete()
データベースへのマイグレーションを理解する
掲示板アプリケーションのデータベースに投稿者の名前を表すカラムを追加していきます。
マイグレーションとは、データベースの中身を一括して移行したり変更したりする作業です。Djangoのマイグレーション機能では、データベースの定義や変更を一度に行うことができます。マイグレーションの取り消し(ロールバック)もできます。
user_nameカラムを追加
# myproject/bbs/models.py from django.db import models class Article(models.Model): # Articleクラスが記事を操作するためのモデル content = models.CharField(max_length=200) user_name = models.CharField(max_length=200, null = True) # user_nameカラムを追加 def __str__(self): return self.content
マイグレーションファイルの作成と実行
$ cd myapp $ python manage.py makemigrations bbs # models.pyを読み取って、マイグレーションファイルを作成 Migrations for 'bbs': bbs/migrations/0002_article_user_name.py - Add field user_name to article $ python manage.py migrate # マイグレーションファイルの実行 Operations to perform: Apply all migrations: admin, auth, bbs, contenttypes, sessions Running migrations: Applying bbs.0002_article_user_name... OK
管理サイトでパスワードを変更
- 管理サイトにログインする
- 「Users」をクリック
- パスワードを変更したいユーザー名をクリック
- 「Change user」-「Password」にある、’Raw passwords are not stored, so there is no way to see this user’s password, but you can change the password using this form.’の最後にあるリンクをクリック
- 「Change password」フォームに新しいパスワードを入力
- 「CHANGE PASSWORD」ボタンをクリック
テンプレートにカラムを追加
モデルに追加したカラムをテンプレートで表示していきます。
index.htmlにカラムを追加
<!-- myapp/bbs/templates/bbs/index.html --> < !DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>paiza bbs</title> <style>body {padding: 10px;}</style> </head> <body> <h1>paiza bbs</h1> <p>{{ message }}</p> {% for article in articles %} <!-- articlesから要素を取り出す --> <p> {{ article.content }},{{ article.user_name }}, <!-- user_nameを追加 --> <a href="{% url 'bbs:detail' article.id %}">詳細</a> </p> {% endfor %} </body> </html>
detail.htmlにカラムを追加
<!-- myapp/bbs/templates/bbs/detail.html --> < !DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>paiza bbs</title> <style>body {padding: 10px;}</style> </head> <body> <h1>paiza bbs</h1> <p>{{ message }}</p> <!-- ビューから受け取った個別の記事データを表示 --> <p>{{ article.content }}, {{ article.user_name }}</p> <!-- user_nameを追加 --> <p><a href="{% url 'bbs:index' %}">一覧</a></p> </body> </html>
Webアプリのデータの流れを理解する
Djangoのルーティングに、新しいルートを追加していきます。
掲示板アプリケーションのルーティング設定
URL | 呼び出す機能 | 関数 |
---|---|---|
bbs/ | 掲示板:記事の一覧表示 | index() |
bbs/(id) | 掲示板:記事の個別表示 | detail() |
new | 記事の作成 | new() |
create | 記事の投稿 | create() |
bbs/(id)/edit | 記事の編集 | edit() |
bbs/(id)/update | 記事の更新 | update() |
bbs/(id)/delete | 記事の削除 | delete() |
ルートを追加
# myapp/myapp/urls.py from django.urls import include, path from django.contrib import admin from django.views.generic import RedirectView # クラスベース汎用ビューを使用 urlpatterns = [ path('bbs/', include('bbs.urls')), path('admin/', admin.site.urls), path('', RedirectView.as_view(url='/bbs/')), # 何も指定しない場合、bbsへリダイレクト ]
データベースに書き込む
urls.pyに「create」を追記する
# myapp/bbs/urls.py from django.urls import path from . import views app_name = 'bbs' urlpatterns = [ path('', views.index, name='index'), path('<int:id>', views.detail, name='detail'), # パスがcreateの場合、viewsのcreate関数を呼び出す path('create', views.create, name='create'), ]
views.pyに「create」関数を追加する
# myapp/bbs/views.py def create(request): article = Article(content='Hello BBS', user_name='paiza') # 固定テキストをセット article.save() articles = Article.objects.all() context = { 'message': 'Create article', 'articles': articles, } return render(request, 'bbs/index.html', context)
新規リンクをテンプレートに追加する
<!-- myapp/bbs/templates/index.html --> < !DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>paiza bbs</title> <style>body {padding: 10px;}</style> </head> <body> <h1>paiza bbs</h1> <p>{{ message }}</p> {% for article in articles %} <p> {{ article.content }},{{ article.user_name }}, <a href="{% url 'bbs:detail' article.id %}">詳細</a> </p> {% endfor %} <p> <!-- ルーティングで指定したcreateをリンク先に指定 --> <a href="{% url 'bbs:create' %}">新規</a> </p> </body> </html>
データベースから記事を削除
ルートで「delete」にアクセスした時、該当の記事を削除する機能を実装していきます。
urls.pyに「delete」を追記
# myapp/bbs/urls.py from django.urls import path from . import views app_name = 'bbs' urlpatterns = [ path('', views.index, name='index'), path('', views.detail, name='detail'), path('create', views.create, name='create'), # idの後がdeleteとなっている場合、viewsのdelete関数を呼び出す path('</int:id><int:id>/delete', views.delete, name='delete'), ]
views.pyに、delete関数を追記
# myapp/bbs/views.py def delete(request, id): # 指定のデータを取り出して、データを削除 article = get_object_or_404(Article, pk=id) article.delete() articles = Article.objects.all() context = { 'message': 'Delete article ' + str(id), 'articles': articles, } return render(request, 'bbs/index.html', context) # 記事一覧を表示
テンプレートに削除リンクを追加
<!-- myapp/bbs/templates/index.html --> < !DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>paiza bbs</title> <style>body {padding: 10px;}</style> </head> <body> <h1>paiza bbs</h1> <p>{{ message }}</p> {% for article in articles %} <p> {{ article.content }},{{ article.user_name }}, <a href="{% url 'bbs:detail' article.id %}">詳細</a>, <!-- ルーティングで指定したdeleteへリンク先を指定 --> 削除 </p> {% endfor %} <p> <a href="{% url 'bbs:create' %}">新規</a> </p> </body> </html>
[siteorigin_widget class=”AdWidgetItem”][/siteorigin_widget]
[siteorigin_widget class=”WP_Widget_Search”][/siteorigin_widget]
[siteorigin_widget class=”WP_Widget_Pages”][/siteorigin_widget]
[siteorigin_widget class=”AdWidgetItem”][/siteorigin_widget]