Djangoを仕事で使っていくために学んだこと

1.5K Views

January 14, 24

スライド概要

https://django.connpass.com/event/295303/ の発表資料

profile-image

勉強中・興味のあるもの: Python / React / DDD / TDD

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

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

2.

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

3.

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

4.

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

5.

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

6.

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

7.

公式リファレンス編

8.

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

9.

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

10.

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

11.

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

12.

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

13.

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

14.

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

15.

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

16.

検索しても 出てこない!?

17.

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

18.

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

19.

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

20.

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

21.

検索しても出てこない!? enで検索した場合

22.

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

23.

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

24.

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

25.

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

26.

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

27.

Model編

28.

Model定義で 失敗した話

29.

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

30.

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

31.

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

32.

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

33.

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

34.

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

35.

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

36.

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

37.

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

38.

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

39.

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

40.

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

41.

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

42.

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

43.

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

44.

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

45.

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

46.

テーブル名に違和感・・・? ● > A model's database table name is constructed by joining the model's "app label" -- the name you used in manage.py startapp -- to the model's class name, with an underscore between them. ● Table names

47.

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

48.

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

49.

QuerySetについて

50.

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

51.

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

52.

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

53.

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

54.

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

55.

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

56.

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

57.

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

58.

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

59.

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

60.

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

61.

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

62.

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

63.

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

64.

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

65.

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

66.
[beta]
SQLが大量に実行される問題
(0.001)
SELECT
"book"."id", "book"."author_id", "book"."title", "book"."release_date", "book"."price"
FROM "book"
WHERE ("book"."title" LIKE '君のことが大大大大大好きな100人の彼女%' ESCAPE '\' AND
"book"."release_date" <= '2023-10-03'); args=('君のことが大大大大大好きな100人の彼女%',
'2023-10-03'); alias=default
(0.000)
SELECT "author"."id", "author"."name"
FROM "author"
WHERE "author"."id" = 1 LIMIT 21; args=(1,); alias=default

✖N回

67.

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

68.

select_related()

69.

select_related() > Returns a QuerySet that will "follow" 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't require database queries. select_related()

70.

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

71.

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

72.

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

73.

django-debug-toolbar

74.

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

75.

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

76.

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

77.

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

78.

objectsお前誰よ?

79.

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

80.

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

81.

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

82.

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

83.

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

84.

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

85.

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

86.

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

87.

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

88.

休憩代わりにクイズ!

89.

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

90.

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

91.

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

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

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

94.

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

95.

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

96.

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

97.

View編

98.

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

99.

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

100.

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

101.

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

102.

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

103.

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

104.

クラスベースビュー 多過ぎ・・・!?

105.

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

106.

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

107.

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

108.

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

109.

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

110.

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

111.

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

112.

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

113.

Template編

114.

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

115.

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

116.

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

117.

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

118.

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

119.

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

120.

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

121.

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

122.

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

123.

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

124.

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

125.

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

126.

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

127.

脱・print()デバッグ

128.

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

129.

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

130.

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

131.

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

132.

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

133.

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

134.

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

135.

python -m pdb manage.py <command> で広がる世界?

136.

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

137.

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

138.

まとめ

139.

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

140.

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

141.

登壇のきっかけ

142.

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

143.

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