---
title: Djangoを仕事で使っていくために学んだこと
tags: 
author: [Tatsuya Nibuno](https://convert.docswell.com/user/nibuno)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/Y7658ZLMEV.jpg?width=480
description: https://django.connpass.com/event/295303/  の発表資料
published: January 14, 24
canonical: https://convert.docswell.com/s/nibuno/5Q8J7W-2024-01-14-145124
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/Y7658ZLMEV.jpg)

Djangoを仕事で
使っていくために学んだこと
DjangoCongress JP 2023
Tatsuya Nibuno


# Page. 2

![Page Image](https://bcdn.docswell.com/page/G75Y9W1Q74.jpg)

このスライドは公開しています


# Page. 3

![Page Image](https://bcdn.docswell.com/page/9J2G2Q1WJR.jpg)

お前誰よ？
● Tatsuya Nibuno (nibu / Yumihiki)
● 株式会社ビープラウド
● 奈良県在住 = フルリモート
● 読書py
● X: @YumihikiDev
● bluesky: nibu


# Page. 4

![Page Image](https://bcdn.docswell.com/page/DEYVYWZ9EM.jpg)

本セッションの内容について
● Djangoを仕事で使ったことのない初学者が
● 使っていくために学んだことを発表


# Page. 5

![Page Image](https://bcdn.docswell.com/page/VJNMP93D78.jpg)

想定聴講者層
● Djangoを学習中・学習し始めの方
○ チュートリアルをちょっと触ってみた程度
● Model, View, Template をそれぞれ概要は知っている


# Page. 6

![Page Image](https://bcdn.docswell.com/page/YE9N3298E3.jpg)

お品書き
● 公式リファレンス編
● Model編
● View編
● Template編
● もう一歩踏み出してみた編
● まとめ


# Page. 7

![Page Image](https://bcdn.docswell.com/page/GE8KM59Z7D.jpg)

公式リファレンス編


# Page. 8

![Page Image](https://bcdn.docswell.com/page/LELZ3YW1JR.jpg)

公式リファレンス、
読んでますか？


# Page. 9

![Page Image](https://bcdn.docswell.com/page/4JMVDN95JW.jpg)

公式リファレンス、読んでますか？
ある日のチャット
● 先輩H: ここのコードはこうした方が良いね。
リファレンスにもこう記述があるし。
● 後輩N: ありがとうございます。確認します！
（レビューでは基本的に公式リファレンスを教えてくれるな・・・
自分も読まねば・・・）


# Page. 10

![Page Image](https://bcdn.docswell.com/page/PJR24DGZE9.jpg)

公式リファレンス、読んでますか？
● 公式リファレンスのどこに何の記載があるかわからなかった


# Page. 11

![Page Image](https://bcdn.docswell.com/page/PEXD21X17X.jpg)

Djangoリファレンスの
おすすめページ


# Page. 12

![Page Image](https://bcdn.docswell.com/page/3EKXM2WM7D.jpg)

Djangoリファレンスのおすすめページ
大きく3つ


# Page. 13

![Page Image](https://bcdn.docswell.com/page/L735Y412E5.jpg)

Djangoリファレンスのおすすめページ
1.Djangoのチュートリアル
● さぁ始めましょう


# Page. 14

![Page Image](https://bcdn.docswell.com/page/87DD5QX67G.jpg)

Djangoリファレンスのおすすめページ
2.Django ドキュメント
● モデル層
● ビュー層
● テンプレート層


# Page. 15

![Page Image](https://bcdn.docswell.com/page/VJPXGLKZ78.jpg)

Djangoリファレンスのおすすめページ
3.さらに一歩進んで・・・
● API Reference
○ 1, 2で紹介したページは基本的な事項や概念の紹介が中心
○ = 詳細な仕様は書かれていない


# Page. 16

![Page Image](https://bcdn.docswell.com/page/2EVL6QVMJQ.jpg)

検索しても
出てこない！？


# Page. 17

![Page Image](https://bcdn.docswell.com/page/57GXNWLXEL.jpg)

検索しても出てこない！？
● QuerySetでLIMIT使いたいな、調べてみよう


# Page. 18

![Page Image](https://bcdn.docswell.com/page/4EQ8Q3Y5JP.jpg)

検索しても出てこない！？
1件だけ、チュートリアルの内容がヒットしたのみ！？
（QuerySetとは関係なさそう・・・）


# Page. 19

![Page Image](https://bcdn.docswell.com/page/KJ42N1WVE1.jpg)

検索しても出てこない！？
● 後輩N: 「QuerySetでLIMIT使えないの・・・？」
● 先輩H: 「本当かな？」 Limiting Querysets
● 後輩N: 「やっぱり出来ますよね・・・」


# Page. 20

![Page Image](https://bcdn.docswell.com/page/LE1M5GY47G.jpg)

検索しても出てこない！？
表示言語によって検索結果が異なる


# Page. 21

![Page Image](https://bcdn.docswell.com/page/GEW35KGZE2.jpg)

検索しても出てこない！？
enで検索した場合


# Page. 22

![Page Image](https://bcdn.docswell.com/page/47ZVNZLLE3.jpg)

検索しても出てこない！？
検索結果の中に
● Making queries がヒット
● （ページの下部に Limiting Querysets がある）
● 自分が欲しかった情報を調べることが出来た！


# Page. 23

![Page Image](https://bcdn.docswell.com/page/YJ658ZWM7V.jpg)

公式リファレンス編まとめ
● 公式リファレンスを読もう
○ 特に、詳細な仕様はAPI Reference を抑えよう
● jaで検索しても出てこない場合はenで一度検索
● 検索結果への登録方法をご存知の方が居たら教えてください！


# Page. 24

![Page Image](https://bcdn.docswell.com/page/GJ5Y9WMQJ4.jpg)

発表後の追記
● 検索結果について
● 発表後 @tokibito さんから以下のアドバイスをもらいました
● &gt; ドキュメント検索はGoogle検索のsite演算子を使うのもあ
り #djangocongress


# Page. 25

![Page Image](https://bcdn.docswell.com/page/LE35Y4WZJ5.jpg)

発表後の追記
使い方
● 検索時に以下のように書く
● &gt; site:https://www.example.com/ramen つけ麺
● &gt; https://www.example.com/ramen で始まり、つけ麺
に関連する URL を含むページの検索結果を表示します。
● site: 検索演算子


# Page. 26

![Page Image](https://bcdn.docswell.com/page/8EDD5QK4EG.jpg)

発表後の追記
● Making queries がヒットしました！


# Page. 27

![Page Image](https://bcdn.docswell.com/page/V7PXGLKVE8.jpg)

Model編


# Page. 28

![Page Image](https://bcdn.docswell.com/page/2JVL6QVR7Q.jpg)

Model定義で
失敗した話


# Page. 29

![Page Image](https://bcdn.docswell.com/page/5EGXNWL6JL.jpg)

Model定義で失敗した話
後輩N: 勉強のために本の管理Modelを考えてみよう！
●
●
著者テーブル
○ 主キー
○ 著者名
本テーブル
○ 主キー
○ 著者テーブル主キー(外部キー)
○ 名前（タイトル）
○ 発売日
○ 値段


# Page. 30

![Page Image](https://bcdn.docswell.com/page/4JQ8Q3Y27P.jpg)

Model定義で失敗した話
後輩N: 主キーは「pk」っていう主キーだとわかる名前にしよう。


# Page. 31

![Page Image](https://bcdn.docswell.com/page/K742N1WPJ1.jpg)

Model定義で失敗した話
from django.db import models
class Author(models.Model):
pk = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, verbose_name=&#039;著者名&#039;)
class Book(models.Model):
pk = models.AutoField(primary_key=True)
author_pk = models.ForeignKey(Author, on_delete=models.CASCADE,
verbose_name=&#039;著者&#039;)
title = models.CharField(max_length=50, verbose_name=&#039;名前（タイトル）&#039;)
release_date = models.DateField(verbose_name=&#039;発売日&#039;)
price = models.IntegerField(verbose_name=&#039;値段&#039;)


# Page. 32

![Page Image](https://bcdn.docswell.com/page/LJ1M5GYXEG.jpg)

Model定義で失敗した話
テーブル作成時に実行するコマンドは以下の2つ
1. python manage.py makemigrations
2. python manage.py migrate
※前提: python manage.py startapp books でアプリ作成済み


# Page. 33

![Page Image](https://bcdn.docswell.com/page/GJW35KGKJ2.jpg)

Model定義で失敗した話
python manage.py makemigrations を実行したら・・・
SystemCheckError: System check identified some issues:
ERRORS:
books.Author.pk: (fields.E003) &#039;pk&#039; is a reserved word that cannot
be used as a field name.
pkは予約語のため使用出来ない


# Page. 34

![Page Image](https://bcdn.docswell.com/page/4EZVNZLNJ3.jpg)

Model定義で失敗した話
&gt; id フィールドは自動的に追加されますが、この処理を無効化す
ることができます。自動インクリメントのプライマリーキーフィールド
を参照ください。
● 簡単な例 技術的な注意点 （モデル）


# Page. 35

![Page Image](https://bcdn.docswell.com/page/Y7658ZW9EV.jpg)

Model定義で失敗した話
後輩N: 主キーは「pk」だとダメだったから「id」としておこう。著者
名テーブルのIDのカラムは「author_id」に修正しておくぞ・・・！


# Page. 36

![Page Image](https://bcdn.docswell.com/page/G75Y9WMD74.jpg)

Model定義で失敗した話
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=50, verbose_name=&#039;著者名&#039;)
class Book(models.Model):
author_id = models.ForeignKey(Author, on_delete=models.CASCADE,
verbose_name=&#039;著者&#039;)
title = models.CharField(max_length=50, verbose_name=&#039;名前（タイトル）&#039;)
release_date = models.DateField(verbose_name=&#039;発売日&#039;)
price = models.IntegerField(verbose_name=&#039;値段&#039;)


# Page. 37

![Page Image](https://bcdn.docswell.com/page/9J2G2QRMJR.jpg)

Model定義で失敗した話
python manage.py makemigrations を実行
Migrations for &#039;books&#039;:
books/migrations/0001_initial.py
- Create model Author
- Create model Book
python manage.py migrate を実行


# Page. 38

![Page Image](https://bcdn.docswell.com/page/DEYVYWDPEM.jpg)

Model定義で失敗した話
後輩N: できました！
先輩M: 出来たように見えるけど、_idは不要かな。
author_id_idというカラム名になっているはず。
後輩N: え、そうなんですか。一度見直してきます！


# Page. 39

![Page Image](https://bcdn.docswell.com/page/VJNMP96M78.jpg)

Model定義で失敗した話
テーブルの中身を見てみよう
python manage.py dbshell
SQLiteの場合
● .tables テーブルの一覧を表示
● .schema &lt;テーブル名&gt; テーブル定義を表示


# Page. 40

![Page Image](https://bcdn.docswell.com/page/YE9N32LWE3.jpg)

Model定義で失敗した話
出来上がったテーブル
● books_author
● books_book
.schema books_book を実行


# Page. 41

![Page Image](https://bcdn.docswell.com/page/GE8KM5XR7D.jpg)

Model定義で失敗した話
CREATE TABLE IF NOT EXISTS &quot;books_book&quot; (
&quot;id&quot; integer NOT NULL PRIMARY KEY AUTOINCREMENT,
&quot;title&quot; varchar(50) NOT NULL,
&quot;release_date&quot; date NOT NULL,
&quot;price&quot; integer NOT NULL,
&quot;author_id_id&quot; bigint NOT NULL REFERENCES &quot;books_author&quot; (&quot;id&quot;) DEFERRABLE
INITIALLY DEFERRED
);
CREATE INDEX &quot;books_book_author_id_id_78aac9b7&quot; ON &quot;books_book&quot;
(&quot;author_id_id&quot;);


# Page. 42

![Page Image](https://bcdn.docswell.com/page/LELZ3Y82JR.jpg)

Model定義で失敗した話
CREATE TABLE IF NOT EXISTS &quot;books_book&quot; (
&quot;id&quot; integer NOT NULL PRIMARY KEY AUTOINCREMENT,
&quot;title&quot; varchar(50) NOT NULL,
&quot;release_date&quot; date NOT NULL,
&quot;price&quot; integer NOT NULL,
&quot;author_id_id&quot; bigint NOT NULL REFERENCES &quot;books_author&quot; (&quot;id&quot;) DEFERRABLE
INITIALLY DEFERRED
);
CREATE INDEX &quot;books_book_author_id_id_78aac9b7&quot; ON &quot;books_book&quot;
(&quot;author_id_id&quot;);


# Page. 43

![Page Image](https://bcdn.docswell.com/page/4JMVDN69JW.jpg)

Model定義で失敗した話
&gt; Behind the scenes, Django appends &quot;_id&quot; to the
field name to create its database column name.
● Database Representation
= _id を裏側で付与してくれる


# Page. 44

![Page Image](https://bcdn.docswell.com/page/PJR24DP9E9.jpg)

テーブル名に違和感・・・？


# Page. 45

![Page Image](https://bcdn.docswell.com/page/PEXD21337X.jpg)

テーブル名に違和感・・・？
今回のテーブル名は
● books_author
● books_book
だった つまり・・・
● App名_Model名 ？
※前提: python manage.py startapp books でアプリケーション作成済


# Page. 46

![Page Image](https://bcdn.docswell.com/page/3EKXM2YN7D.jpg)

テーブル名に違和感・・・？
● &gt; A model&#039;s database table name is constructed
by joining the model&#039;s &quot;app label&quot; -- the name
you used in manage.py startapp -- to the model&#039;s
class name, with an underscore between them.
● Table names


# Page. 47

![Page Image](https://bcdn.docswell.com/page/L735Y49ZE5.jpg)

テーブル名に違和感・・・？
Modelには内部クラスのMeta optionsが存在する
● Model Meta options
● db_table = &quot;author&quot;
● db_table = &quot;book&quot;
と定義 = テーブル名が author, book に


# Page. 48

![Page Image](https://bcdn.docswell.com/page/87DD5QG47G.jpg)

テーブル名に違和感・・・？
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=50, verbose_name=&#039;著者名&#039;)
class Meta:
db_table = &quot;author&quot;
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE, verbose_name=&#039;著者&#039;)
title = models.CharField(max_length=50, verbose_name=&#039;名前（タイトル） &#039;)
release_date = models.DateField(verbose_name=&#039;発売日&#039;)
price = models.IntegerField(verbose_name=&#039;値段&#039;)
class Meta:
db_table = &quot;book&quot;


# Page. 49

![Page Image](https://bcdn.docswell.com/page/VJPXGL3V78.jpg)

QuerySetについて


# Page. 50

![Page Image](https://bcdn.docswell.com/page/2EVL6Q4RJQ.jpg)

QuerySetについて
DB操作をするためのAPI
book = Book.objects.all()
と記述するだけで、BookModelの全データ（レコード）を取得可能
● QuerySet API リファレンス


# Page. 51

![Page Image](https://bcdn.docswell.com/page/57GXNW16EL.jpg)

QuerySetについて
後輩N: QuerySetはSQL書かなくて良い... 便利だなぁ
先輩T: 便利なだけではなくて、QuerySetには
「遅延評価される」
「キャッシュされる」という特徴が
あるので覚えておくと役立つ時が来るかもしれません。
後輩N: そうなんですね。なるほど！（全然知らなかった・・・）


# Page. 52

![Page Image](https://bcdn.docswell.com/page/4EQ8Q3D2JP.jpg)

DjangoのQuerySetは遅延評価される
1.遅延評価について
● 必要なタイミングで評価（=実行）されること


# Page. 53

![Page Image](https://bcdn.docswell.com/page/KJ42N1ZPE1.jpg)

DjangoのQuerySetは遅延評価される
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; q = Book.objects.filter(title__startswith=&quot;君のことが大大大大大好きな100人
の彼女&quot;)
&gt;&gt;&gt; q = q.filter(release_date__lte=date.today())
&gt;&gt;&gt; for book in q:
...
print(book.title, book.author.name)


# Page. 54

![Page Image](https://bcdn.docswell.com/page/LE1M5GRX7G.jpg)

DjangoのQuerySetは遅延評価される
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; q = Book.objects.filter(title__startswith=&quot;君のことが大大大大大好きな100人
の彼女&quot;)
&gt;&gt;&gt; q = q.filter(release_date__lte=date.today())
&gt;&gt;&gt; for book in q:
...
print(book.title, book.author.name)


# Page. 55

![Page Image](https://bcdn.docswell.com/page/GEW35K1KE2.jpg)

DjangoのQuerySetは遅延評価される
●
●
●
●
●
●
●
●
イテレーション
スライス
Pickle化/キャッシュ化
repr()
len()
list()
bool()
When QuerySets are evaluated


# Page. 56

![Page Image](https://bcdn.docswell.com/page/47ZVNZPNE3.jpg)

DjangoのQuerySetは遅延評価される
QuerySet は遅延評価される


# Page. 57

![Page Image](https://bcdn.docswell.com/page/YJ658ZM97V.jpg)

QuerySetはキャッシュされる
2.キャッシュについて
● QuerySetが評価されたタイミングでキャッシュに保存される
● キャッシングとQuerySet


# Page. 58

![Page Image](https://bcdn.docswell.com/page/GJ5Y9WZDJ4.jpg)

QuerySetはキャッシュされる
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; q = Book.objects.all()
&gt;&gt;&gt; print([book.title for book in q]) # データベースから取得
&gt;&gt;&gt; print([book.release_date for book in q]) # キャッシュから取得


# Page. 59

![Page Image](https://bcdn.docswell.com/page/9E2G2QPMER.jpg)

QuerySetはキャッシュされる
一方で、このように書いてしまうと
毎回データベースへの問い合わせが発生してしまう・・・
&gt;&gt;&gt; print([book.title for book in Book.objects.all()])
&gt;&gt;&gt; print([book.release_date for book in Book.objects.all()])


# Page. 60

![Page Image](https://bcdn.docswell.com/page/D7YVYW5P7M.jpg)

QuerySetはキャッシュされる
● &gt; QuerySet を理解することは、シンプルなコードでパフォー
マンスを上げるために極めて重要です。
● QuerySet を理解する


# Page. 61

![Page Image](https://bcdn.docswell.com/page/VENMP9NMJ8.jpg)

SQLが大量に
実行される問題


# Page. 62

![Page Image](https://bcdn.docswell.com/page/Y79N32RW73.jpg)

SQLが大量に実行される問題
QuerySetは万能なものでは無い
先ほど紹介した遅延評価のコードにも潜んでいた・・・


# Page. 63

![Page Image](https://bcdn.docswell.com/page/G78KM5WRJD.jpg)

SQLが大量に実行される問題
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; q = Book.objects.filter(title__startswith=&quot;君のことが大大大大大好きな100人
の彼女&quot;)
&gt;&gt;&gt; q = q.filter(release_date__lte=date.today())
&gt;&gt;&gt; for book in q:
...
print(book.title, book.author.name)


# Page. 64

![Page Image](https://bcdn.docswell.com/page/L7LZ3YN2ER.jpg)

SQLが大量に実行される問題
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; q = Book.objects.filter(title__startswith=&quot;君のことが大大大大大好きな100人
の彼女&quot;)
1回（=イテレート時）
&gt;&gt;&gt; q = q.filter(release_date__lte=date.today())
&gt;&gt;&gt; for book in q:
...
print(book.title, book.author.name)


# Page. 65

![Page Image](https://bcdn.docswell.com/page/4EMVDNX9EW.jpg)

SQLが大量に実行される問題
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; q = Book.objects.filter(title__startswith=&quot;君のことが大大大大大好きな100人
の彼女&quot;)
&gt;&gt;&gt; q = q.filter(release_date__lte=date.today())
N回（qでヒットした数の回数）
&gt;&gt;&gt; for book in q:
...
print(book.title, book.author.name)


# Page. 66

![Page Image](https://bcdn.docswell.com/page/PER24DN979.jpg)

SQLが大量に実行される問題
(0.001)
SELECT
&quot;book&quot;.&quot;id&quot;, &quot;book&quot;.&quot;author_id&quot;, &quot;book&quot;.&quot;title&quot;, &quot;book&quot;.&quot;release_date&quot;, &quot;book&quot;.&quot;price&quot;
FROM &quot;book&quot;
WHERE (&quot;book&quot;.&quot;title&quot; LIKE &#039;君のことが大大大大大好きな100人の彼女%&#039; ESCAPE &#039;\&#039; AND
&quot;book&quot;.&quot;release_date&quot; &lt;= &#039;2023-10-03&#039;); args=(&#039;君のことが大大大大大好きな100人の彼女%&#039;,
&#039;2023-10-03&#039;); alias=default
(0.000)
SELECT &quot;author&quot;.&quot;id&quot;, &quot;author&quot;.&quot;name&quot;
FROM &quot;author&quot;
WHERE &quot;author&quot;.&quot;id&quot; = 1 LIMIT 21; args=(1,); alias=default
✖N回


# Page. 67

![Page Image](https://bcdn.docswell.com/page/P7XD21N3JX.jpg)

SQLが大量に実行される問題
● N+1問題
● 今回のケースだと
● select_releted()を使用することで回避できる


# Page. 68

![Page Image](https://bcdn.docswell.com/page/37KXM2NNJD.jpg)

select_related()


# Page. 69

![Page Image](https://bcdn.docswell.com/page/LJ35Y4VZ75.jpg)

select_related()
&gt; Returns a QuerySet that will &quot;follow&quot; foreign-key
relationships, selecting additional related-object
data when it executes its query. This is a
performance booster which results in a single more
complex query but means later use of foreign-key
relationships won&#039;t require database queries.
select_related()


# Page. 70

![Page Image](https://bcdn.docswell.com/page/8JDD5Q84JG.jpg)

select_related()
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; books =
Book.objects.select_related(&#039;author&#039;).filter(title__startswith=&quot;君のことが大
大大大大好きな100人の彼女&quot;)
&gt;&gt;&gt; for book in books:
...
print(book.title, book.author.name)


# Page. 71

![Page Image](https://bcdn.docswell.com/page/VEPXGL8VJ8.jpg)

select_related()
&gt;&gt;&gt; from books.models import Book
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; books =
Book.objects.select_related(&#039;author&#039;).filter(title__startswith=&quot;君のことが大
大大大大好きな100人の彼女&quot;)
&gt;&gt;&gt; for book in books:
...
print(book.title, book.author.name)


# Page. 72

![Page Image](https://bcdn.docswell.com/page/27VL6QNREQ.jpg)

select_related()
裏側で発行されるSQL 1回に減った！
(0.001)
SELECT &quot;book&quot;.&quot;id&quot;, &quot;book&quot;.&quot;author_id&quot;, &quot;book&quot;.&quot;title&quot;, &quot;book&quot;.&quot;release_date&quot;, &quot;book&quot;.&quot;price&quot;,
&quot;author&quot;.&quot;id&quot;, &quot;author&quot;.&quot;name&quot;
FROM &quot;book&quot;
INNER JOIN &quot;author&quot; ON (&quot;book&quot;.&quot;author_id&quot; = &quot;author&quot;.&quot;id&quot;)
WHERE &quot;book&quot;.&quot;title&quot; LIKE &#039;君のことが大大大大大好きな100人の彼女%&#039; ESCAPE &#039;\&#039;; args=(&#039;君のこと
が大大大大大好きな100人の彼女%&#039;,); alias=default


# Page. 73

![Page Image](https://bcdn.docswell.com/page/5JGXNWK67L.jpg)

django-debug-toolbar


# Page. 74

![Page Image](https://bcdn.docswell.com/page/47Q8Q3N2EP.jpg)

django-debug-toolbar
Djangoのデバッグに役立つ3rdPartyLibrary
チュートリアルにも掲載されている
● Django Debug Toolbarをインストールする


# Page. 75

![Page Image](https://bcdn.docswell.com/page/KE42N1GP71.jpg)

django-debug-toolbar
使い方（導入の仕方）は公式ドキュメントを参考に
Installation


# Page. 76

![Page Image](https://bcdn.docswell.com/page/L71M5GDXJG.jpg)

django-debug-toolbar
注意点:&lt;body&gt;タグが必要
= Djangoチュートリアルのコードではそのままだと動かない
&gt; チュートリアルを短くするために、すべてのテンプレートの例では
不完全なHTMLを使用しています。
実際に動作するビューを書く


# Page. 77

![Page Image](https://bcdn.docswell.com/page/G7W35KYK72.jpg)

django-debug-toolbar
SQLタブを
クリックすると
このような画面に


# Page. 78

![Page Image](https://bcdn.docswell.com/page/4JZVNZXN73.jpg)

objectsお前誰よ？


# Page. 79

![Page Image](https://bcdn.docswell.com/page/YE658Z49JV.jpg)

objectsお前誰よ？
● SQLを書かなくてもデータが簡単に取れて楽で良いなぁ
● Model名.objects.all() のように書くだけ、便利
● あれ、そういえばobjectsって誰？


# Page. 80

![Page Image](https://bcdn.docswell.com/page/GE5Y9WQDE4.jpg)

objectsお前誰よ？
● マネージャ（Manager）と呼ばれるクラス
● 1つのモデルに対して、最低でも1つ存在する
● デフォルトで定義されているマネージャ = objects だった
マネージャ


# Page. 81

![Page Image](https://bcdn.docswell.com/page/972G2QWM7R.jpg)

objectsお前誰よ？
なるほど、マネージャというものだとはわかった
● 何のために存在してるの？


# Page. 82

![Page Image](https://bcdn.docswell.com/page/DJYVYWLPJM.jpg)

objectsお前誰よ？
&gt;Manager はモデルのインスタンスでなく、モデルのクラスを経
由してのみアクセスでき、それは &quot;テーブル水準&quot; の処理と &quot;レコー
ド水準&quot; の処理とで責任を明確に分離するためです。
オブジェクトを取得する


# Page. 83

![Page Image](https://bcdn.docswell.com/page/V7NMP94ME8.jpg)

objectsお前誰よ？
&gt;オブジェクトに独自の &quot;行レベルの&quot; 機能を追加するには、カスタ
ムのメソッドを定義してください。Manager メソッドは &quot;テーブル
単位の&quot; 操作をするように意図されており、モデルメソッドは特定
のモデルインスタンス上で動作します。
モデルのメソッド


# Page. 84

![Page Image](https://bcdn.docswell.com/page/YJ9N32QWJ3.jpg)

objectsお前誰よ？
自分なりの解釈
● 「テーブル」単位での処理を行う責務を担う
● all()やfilter()といったものはテーブル単位だった


# Page. 85

![Page Image](https://bcdn.docswell.com/page/GJ8KM5GRED.jpg)

objectsお前誰よ？
objectsは単なる呪文から・・・
テーブル単位での処理を行ってくれるものが
マネージャだと認識できるようになった
● これでひとつ解像度が上がった！（はず）


# Page. 86

![Page Image](https://bcdn.docswell.com/page/LJLZ3YG27R.jpg)

Model編まとめ
● Modelの裏側の挙動を抑えよう
● QuerySetは遅延評価・キャッシュされる
○ 万能の魔法ではない = SQLを確認しよう
■ django-debug-toolbar がおすすめ
● objects = マネージャ
○ 「テーブル」単位での処理を担当する


# Page. 87

![Page Image](https://bcdn.docswell.com/page/47MVDNQ97W.jpg)

そろそろ折り返し
（というかちょっと
超えている）


# Page. 88

![Page Image](https://bcdn.docswell.com/page/P7R24D89J9.jpg)

休憩代わりにクイズ！


# Page. 89

![Page Image](https://bcdn.docswell.com/page/PJXD2183EX.jpg)

休憩代わりにクイズ！
Q. Djangoのリファレンスには
単語数が何語あると記載されているでしょうか？
（ex: 1,000語 | 10,000語 | 100,000語）
心の中でちょっと考えてみてください！


# Page. 90

![Page Image](https://bcdn.docswell.com/page/3JKXM2KNED.jpg)

Djangoのドキュメントは450,000語
A. 450,000語
&gt; Djangoにはたくさんのドキュメント -- （ 約450,000語）があ
るので、必要なものを見つけるのは難しい場合があります。開始す
るのに適した場所は、索引 です。また、組み込みの検索機能を使用
することをお勧めします。
ドキュメントの探し方


# Page. 91

![Page Image](https://bcdn.docswell.com/page/LE35Y4ZZJ5.jpg)

Djangoのドキュメントは450,000語？
en の 1.10 ver と 4.2 ver で同じ表記だった
・・・現在はもっとあるのでは？
どういう結果になったと思いますか？


# Page. 92

![Page Image](https://bcdn.docswell.com/page/8EDD5QR4EG.jpg)

Djangoのドキュメントは450,000語？
● リファレンスをダウンロード
● find docs -name &quot;*.txt&quot; -exec cat {} + | wc -w
○ 出力結果:


# Page. 93

![Page Image](https://bcdn.docswell.com/page/V7PXGLWVE8.jpg)

Djangoのドキュメントは450,000語？
● リファレンスをダウンロード
● find docs -name &quot;*.txt&quot; -exec cat {} + | wc -w
○ 出力結果: 690,558


# Page. 94

![Page Image](https://bcdn.docswell.com/page/2JVL6Q8R7Q.jpg)

Djangoのドキュメントは450,000語？
● commit履歴は2013年1月29日
● ver1.5開発中の時期？
○ Django 1.5 release notes
● ver1.6から450,000語と表記


# Page. 95

![Page Image](https://bcdn.docswell.com/page/5EGXNW56JL.jpg)

Djangoのドキュメントは450,000語？
● stable/1.4x
○ 423066
● stable/1.5x
○ 459318
● stable/1.6x
○ 489616


# Page. 96

![Page Image](https://bcdn.docswell.com/page/4JQ8Q3Z27P.jpg)

Djangoのドキュメントは690,000語かも
● まとめ
● リファレンスには450,000語と記載がある
○ 10年前のものみたい
● 今はDjangoの単語数は690,000語かも
● 以上、小ネタでした


# Page. 97

![Page Image](https://bcdn.docswell.com/page/K742N13PJ1.jpg)

View編


# Page. 98

![Page Image](https://bcdn.docswell.com/page/LJ1M5G1XEG.jpg)

関数ベースビューと
クラスベースビュー


# Page. 99

![Page Image](https://bcdn.docswell.com/page/GJW35K8KJ2.jpg)

関数ベースビューとクラスベースビュー
ある日の休日
後輩N: そういえば、関数ベースビューとクラスベースビューがある
けど、何が違うんだろう。ちょっと調べてみよう。
リファレンスに無いかな・・・ あった！


# Page. 100

![Page Image](https://bcdn.docswell.com/page/4EZVNZ8NJ3.jpg)

関数ベースビューとクラスベースビュー
&gt; クラスベースビューは関数ベースのビューを完全に置き換えるも
のではありませんが、関数ベースのビューと比較して、以下のよう
な違いと利点があります。
クラスベースビュー入門


# Page. 101

![Page Image](https://bcdn.docswell.com/page/Y7658ZP9EV.jpg)

関数ベースビューとクラスベースビュー
&gt; ・特定の HTTP メソッド (GET 、 POST など) に関連するコー
ドの集まりを、条件分岐を使ってかき分けるのではなく、それぞれ
に独立したメソッドを割り当てることができる。
&gt; ・ミックスイン (多重継承) などのオブジェクト指向のテクニック
を使って、コードを再利用可能なコンポーネントに分解できる。
クラスベースビュー入門


# Page. 102

![Page Image](https://bcdn.docswell.com/page/G75Y9WKD74.jpg)

関数ベースビューとクラスベースビュー
関数ベースビュー
クラスベースビュー
from django.http import HttpResponse
from django.http import HttpResponse
from django.views import View
def my_view(request):
if request.method == &quot;GET&quot;:
class MyView(View):
def get(self, request):
# &lt;view logic&gt;
# &lt;view logic&gt;
return HttpResponse(&quot;result&quot;)
return HttpResponse(&quot;result&quot;)
クラスベースのビューを使用する より引用


# Page. 103

![Page Image](https://bcdn.docswell.com/page/9J2G2Q6MJR.jpg)

関数ベースビューとクラスベースビュー
基本的にはクラスベースビューで良さそうだという結論


# Page. 104

![Page Image](https://bcdn.docswell.com/page/DEYVYW9PEM.jpg)

クラスベースビュー
多過ぎ・・・！？


# Page. 105

![Page Image](https://bcdn.docswell.com/page/VJNMP9LM78.jpg)

クラスベースビュー多過ぎ・・・！？
ある日の出来事
● 後輩N: View、種類が多くて調べるのに時間がかかる・・・
● 先輩Y: Viewを調べるとき、こういうの使っています😺
Classy Class-Based Views
● 後輩N: ありがとうございます！初めて知りました！
● 先輩K: （この前紹介してたやつだけど黙っておこう・・・）


# Page. 106

![Page Image](https://bcdn.docswell.com/page/YE9N324WE3.jpg)

クラスベースビュー多過ぎ・・・！？
クラスベースビューには次のようなものがある
● View
● FormView
● ArchiveIndexView
● TemplateView ● CreateView ● YearArchiveView
● RedirectView ● UpdateView ● WeekArchiveView
● DetailView
● ListView
● DeleteView ● DayArchiveView
● etc…


# Page. 107

![Page Image](https://bcdn.docswell.com/page/GE8KM5QR7D.jpg)

クラスベースビュー多過ぎ・・・！？
属性
メソッド
● content_type
● get_queryset
● context_object_name
● form_valid
● template_name
● form_invalid
● queryset
● get
● success_url
● post
● etc…
● etc…


# Page. 108

![Page Image](https://bcdn.docswell.com/page/LELZ3YX2JR.jpg)

クラスベースビュー多過ぎ・・・！？
ビルトインのクラスベースビュー API を見てみるも・・・
ちょっと分かりにくい気もする・・・


# Page. 109

![Page Image](https://bcdn.docswell.com/page/4JMVDNL9JW.jpg)

クラスベースビュー多過ぎ・・・！？
&gt; この索引は、クラスベースビューのリファレンス文書を、異なる観
点から編成したものです。ビューごとに、クラスツリーの有効な属性
とメソッドが表されます。
クラスベース汎用ビュー - フラットインデックス


# Page. 110

![Page Image](https://bcdn.docswell.com/page/PJR24DK9E9.jpg)

クラスベースビュー多過ぎ・・・！？
Classy Class-Based Views
クラスベース汎用ビュー - フラットインデックス 内でも紹介あり


# Page. 111

![Page Image](https://bcdn.docswell.com/page/PEXD21L37X.jpg)

クラスベースビュー多過ぎ・・・！？
Classy Class-Based Viewsは何が良いのか？
● Hierarchy diagram で継承の流れが一目でわかる
● ドキュメント・ソースコードへのリンクがある
● 属性・メソッドの一覧が定義元のクラスを含めてわかる


# Page. 112

![Page Image](https://bcdn.docswell.com/page/3EKXM2LN7D.jpg)

View編まとめ
● クラスベースビューを基本的に用いれば良さそう
● Viewを調べるときには次のリンクがおすすめ
○ クラスベース汎用ビュー - フラットインデックス
○ Classy Class-Based Views


# Page. 113

![Page Image](https://bcdn.docswell.com/page/L735Y43ZE5.jpg)

Template編


# Page. 114

![Page Image](https://bcdn.docswell.com/page/87DD5Q447G.jpg)

Templateで
フィルタを活用しよう


# Page. 115

![Page Image](https://bcdn.docswell.com/page/VJPXGLMV78.jpg)

Templateでフィルタを活用しよう
● 後輩N: ここまで、ModelとViewを調べてきた。
Templateについても勉強していくぞ。
● 後輩N: あれ、このフィルタを利用すれば、
ViewでTemplate表示用のロジックを作らなくて良い・・・？


# Page. 116

![Page Image](https://bcdn.docswell.com/page/2EVL6Q9RJQ.jpg)

Templateでフィルタを活用しよう
フィルタとは？
● 出力時に変数を変換できる
● フィルタを利用することで責務を分離できる
● 組み込みフィルタリファレンス


# Page. 117

![Page Image](https://bcdn.docswell.com/page/57GXNWZ6EL.jpg)

Templateでフィルタを活用しよう
DateFieldの値を出力する例
● {{ book.release_date }}
● 2023年10月4日
○ と出力される
● ※setting.py の LANGUAGE_CODE = &#039;ja&#039; の場合


# Page. 118

![Page Image](https://bcdn.docswell.com/page/4EQ8Q3L2JP.jpg)

Templateでフィルタを活用しよう
DateFieldの値を出力する例
● {{ book.release_date|date:&quot;Y/m/d&quot; }}
● 2023/10/07
○ のように出力できる


# Page. 119

![Page Image](https://bcdn.docswell.com/page/KJ42N1DPE1.jpg)

Templateでフィルタを活用しよう
他にも
● filesizeformat
○ 人間が読みやすいファイルサイズの表現に変換してくれる
● length
○ len() のように数を取得することができる
などなど多数のフィルタが存在する


# Page. 120

![Page Image](https://bcdn.docswell.com/page/LE1M5GZX7G.jpg)

Template編まとめ
● フィルタを積極的に使っていこう


# Page. 121

![Page Image](https://bcdn.docswell.com/page/GEW35K9KE2.jpg)

もう一歩
踏み出してみた編


# Page. 122

![Page Image](https://bcdn.docswell.com/page/47ZVNZ9NE3.jpg)

もう一歩踏み出してみた編
ある休日
● 後輩N: Djangoについて調べていたらソースコードを
読んでいる人や、開発している人が多いなぁ・・・
よし、自分もソースコードを見たり、開発するか。
そういえばModelを作成するときにちょっと詰まったし、
見てみようかな。


# Page. 123

![Page Image](https://bcdn.docswell.com/page/YJ658ZK97V.jpg)

システムチェック
フレームワーク
お前だったのか


# Page. 124

![Page Image](https://bcdn.docswell.com/page/GJ5Y9WPDJ4.jpg)

システムチェックフレームワークお前だったのか
makemigrations 実行時に出たエラー
SystemCheckError: System check identified some issues:
ERRORS:
books.Author.pk: (fields.E003) &#039;pk&#039; is a reserved word that cannot
be used as a field name.


# Page. 125

![Page Image](https://bcdn.docswell.com/page/LE35Y46QJ5.jpg)

システムチェックフレームワークお前だったのか
django/django/db/models/fields /__init__.py L292
elif self.name == &quot;pk&quot;:
return [checks.Error(&quot;&#039;pk&#039; is a reserved word that cannot be
used as a field name.&quot;, obj=self, id=&quot;fields.E003&quot;, )]
else:
※スライドで見やすいように一部改行等を加えています


# Page. 126

![Page Image](https://bcdn.docswell.com/page/8EDD5QVWEG.jpg)

システムチェックフレームワークお前だったのか
● システムチェックフレームワーク
● モデルフィールド
○ CharFieldsにはmax_length を定義しないといけない
○ フィールド名はアンダースコアで終わってはいけない
● 関連フィールド、モデル、etc…
○ 他にもシステムチェックフレームワークがたくさん
チェックしてくれていることがわかった


# Page. 127

![Page Image](https://bcdn.docswell.com/page/V7PXGLVXE8.jpg)

脱・print()デバッグ


# Page. 128

![Page Image](https://bcdn.docswell.com/page/2JVL6QZ37Q.jpg)

脱・print()デバッグ
● 先輩M: そういえばprint()でデバッグしているみたいだけど、
デバッガを使うのが便利だよ
● 後輩N: （え、デバッガ、面倒そう・・・)そうなんですね
● 先輩M: pdbなら1行書くだけで簡単に利用できるよ


# Page. 129

![Page Image](https://bcdn.docswell.com/page/5EGXNW4YJL.jpg)

脱・print()デバッグ
● print()
● 値を調べるためにコードを毎回書き・動かす必要がある
● print(foo)
● print(bar)
●
= 調べたい値を確認するのに手間がかかる


# Page. 130

![Page Image](https://bcdn.docswell.com/page/4JQ8Q3G67P.jpg)

脱・print()デバッグ
&gt;Python プログラム用の対話型ソースコードデバッガ
● pdb --- Python デバッガ
● breakpoint()
と記述するだけでOK
記述した箇所で、実行時にSTOPして確認できる


# Page. 131

![Page Image](https://bcdn.docswell.com/page/K742N15MJ1.jpg)

脱・print()デバッグ
● l(ist) 現在どこにいるか表示
○ ll ソースコードのスコープを広げて表示
● c(ont(inue)) 次のbreakpointまで実行
● p 値を出力する
● q(uit) デバッガの終了


# Page. 132

![Page Image](https://bcdn.docswell.com/page/LJ1M5GWYEG.jpg)

脱・print()デバッグ
● s(tep) 現在の行を実行する
○ 関数の中に入る = 1行ずつ、stepで実行する
● n(ext) 現在の行を実行して次の行で停止する
○ 関数の中に入らない


# Page. 133

![Page Image](https://bcdn.docswell.com/page/GJW35K61J2.jpg)

脱・print()デバッグ
s
def main():
n
def main():
breakpoint()
breakpoint()
foo()
foo()
return True
return True
def foo():
def foo():
pass
pass


# Page. 134

![Page Image](https://bcdn.docswell.com/page/4EZVNZYXJ3.jpg)

脱・print()デバッグ
ソースコードを見る場合
● breakpoint() を書く
● s or n を利用して現在の行を実行する
○ 中身を知りたいobjectがあればsを使う
● l or ll で周囲のコードを調べる
● 手間・時間はかかるけど、中身を見ていくことができるよ！


# Page. 135

![Page Image](https://bcdn.docswell.com/page/Y7658ZDPEV.jpg)

python -m pdb
manage.py
&lt;command&gt;
で広がる世界？


# Page. 136

![Page Image](https://bcdn.docswell.com/page/G75Y9W3P74.jpg)

python -m pdb manage.py
&lt;command&gt;で広がる世界？
pdbを利用した状態でコマンドを実行できる
● python -m pdb manage.py &lt;command&gt;
活用すれば、Djangoの世界をもっと広げていけるかも・・・！？


# Page. 137

![Page Image](https://bcdn.docswell.com/page/9J2G2QZZJR.jpg)

もう一歩踏み出してみた編まとめ
● システムチェックフレームワークという概念が存在していた
● ソースコードも読んでいこう
● pdbを活用しよう


# Page. 138

![Page Image](https://bcdn.docswell.com/page/DEYVYWRNEM.jpg)

まとめ


# Page. 139

![Page Image](https://bcdn.docswell.com/page/VJNMP9DV78.jpg)

Djangoを仕事で使っていくために学んだこと
● リファレンスを読もう
● Djangoの機能を正しく理解しよう
● 一歩進んでソースコードも読んでみよう


# Page. 140

![Page Image](https://bcdn.docswell.com/page/YE9N32GVE3.jpg)

Djangoを仕事で使っていくために学んだこと
聴講者の皆様
ご清聴ありがとうございました！
スタッフの皆様
イベントの主催・運営ありがとうございました！
ビープラウドの皆様
ご協力・ご指導ありがとうございました！


# Page. 141

![Page Image](https://bcdn.docswell.com/page/GE8KM5V47D.jpg)

登壇のきっかけ


# Page. 142

![Page Image](https://bcdn.docswell.com/page/LELZ3Y5VJR.jpg)

登壇のきっかけ
● 後輩N: ハァ... 困ったなァ... DjangoCongress JP 2023
のトーク、申し込みたい気持ちはあるんだけどなァ...
経験少ないから躊躇しちゃってェ...
● 先輩K: 未経験から仕事でDjangoを使うにあたって
取り組んだこととかで出すと良いと思います！


# Page. 143

![Page Image](https://bcdn.docswell.com/page/4JMVDN3NJW.jpg)

ご清聴ありがとうございました！！
ご清聴ありがとうございました！！
We Are Hiring !
Pythonエンジニア
カジュアル面談
https://www.beproud.jp/careers/python/
https://onl.tw/LPVc2hd


