Djangoにはじめて貢献する

はじめに

小さなものでも、コミュニティへ恩返しすることに興味がありますか? たとえば、Django に直してほしいバグを見つけたり、ちょっとした機能を追加してほしいと思っているかもしれません。

その願いを叶える一番の方法は Django 自体にコントリビュートすることです。最初はすごく大変なことだと想像するかもしれませんが、あなたを助けてくれるドキュメント、ツール、コミュニティとともに多くの人が通る道でもあります。これからコントリビュートのプロセス全体を順番に詳しく解説していくので、例を通して理解できると思います。

このチュートリアルの対象者は誰ですか?

参考

パッチを書く方法の細かい参照文献を探しているなら Contributing code ドキュメントを参照してください。

このチュートリアルでは、少なくとも Django がどのように動作するかについて基本的な理解を持っていることを期待します。つまり、 はじめての Django アプリ作成 にある既存のチュートリアルを一通り読んで慣れている必要があります。加えて、Python 自体をよく理解している必要があります。しかし、もしそうでなければ、 Dive Into Python は Python プログラマの初心者のための素晴らしい (そして無料の) オンラインブックです。

バージョン管理システムや Trac をよく知らない方でも、このチュートリアルとリンク先から、コントリビュートに必要な情報は十分得られます。しかし、Django に定期的に貢献したい場合は、このツールの詳細を知っておいた方がいいでしょう。

このチュートリアルでは、できるだけ多くの方が使用できるように、可能な限り詳しく説明したいと思います。

困ったときは:

If you're having trouble going through this tutorial, please post a message on the Django Forum, django-developers, or drop by the Django Discord server to chat with other Django users who might be able to help.

このチュートリアルはどの範囲をカバーしていますか?

これから、Djangoへの初めてのコントリビューションについて説明します。このチュートリアルの終わりまでに、使用するツールと関連するプロセスの基本を理解できるようになります。具体的には、以下の内容を取り上げます。

  • Git のインストール

  • Django 開発版の複製をダウンロードする

  • Django のテストスイートの実行

  • 変更のためのテストを書く

  • 変更のためのコードを書く

  • 変更をテストする

  • プルリクエストを送る

  • より多くの情報を得る方法

チュートリアルを終えたら、次は Django への貢献 を参照してください。このドキュメントには、多くの重要な情報が含まれており、Django に定期的に貢献したい方は是非一読してください。あなたの疑問への答えが見つかるはずです。

3系の Python が必要です!

Django の現在のバージョンは、Python 2.7 をサポートしません。Python のダウンロードページ や OS のパッケージ管理システムを用いて Python 3 をインストールしてください。

Windows を使用している方へ

Windowsのドキュメントの Python をインストールする をみてください。

ソースコードの管理

Django へ貢献を行う上では、Django コミュニティをオープンで誰にでも開かれたものに保つよう心がけてください。 行動規範 をよく読み、それに従ってください。

Git のインストール

このチュートリアルでは、Djangoの現在の開発バージョンをダウンロードし、変更内容に対応するブランチを作成するために、Git をインストールしておく必要があります。

Git がインストールされているかどうかを確認するために、コマンドラインで git を入力します。もし入っていない場合は、ダウンロード及びインストールするために、 Git's download page を参照してください。

もし Git について詳しく知らない場合は、(インストール後に) コマンドラインから git help と入力するとコマンドの使い方を確認できます。

Django 開発版の複製を取得

Django へ貢献するためのはじめの一歩は、ソースコードのコピーです。まず、 GitHub で Django をフォーク して、コマンドラインからリポジトリのクローンを作り、 cd コマンドで Django のローカルコピーのディレクトリに移動しましょう。

以下のコマンドで Django のソースコードリポジトリをダウンロードします:

$ git clone https://github.com/YourGitHubName/django.git
...\> git clone https://github.com/YourGitHubName/django.git

低帯域の回線をご利用ですか?

git clone--depth 1 という引数を追加すると、Djangoのコミット履歴のダウンロードをスキップすることができます。これによってデータの転送量が70〜250MB程度減ります。

Django のローカルコピーがあるので、 pip を使ってパッケージをインストールするのと同じようにインストールすることができます。そのための最も便利な方法は、Python に組み込まれている機能である 仮想環境 を使用することです。これにより、相互に干渉しないようにプロジェクトごとにインストールされたパッケージの別々のディレクトリを保つことができます。

例えばホームディレクトリ下の .virtualenvs/ にすべての仮想環境を置くことが出来ます。

次のコマンドで、新しい仮想環境を作成します:

$ python3 -m venv ~/.virtualenvs/djangodev
...\> py -m venv %HOMEPATH%\.virtualenvs\djangodev

新しい環境があるパスはコンピュータに保存されました。

最後のステップとして仮想環境を有効化します:

$ source ~/.virtualenvs/djangodev/bin/activate

もし source コマンドが使えない場合、代わりに . を試してみてください:

$ . ~/.virtualenvs/djangodev/bin/activate

新しいターミナルウィンドウを開くたびに仮想環境を有効にする必要があります。

Windows を使用している方へ

実行してWindowsでの仮想環境を有効化します:

...\> %HOMEPATH%\.virtualenvs\djangodev\Scripts\activate.bat

その時点で有効な仮想環境の名前がコマンドライン上に表示されます。これによってどの仮想環境を利用しているのかが分かります。仮想環境のもとで pip によるインストールを行うと、表示されている仮想環境内にインストールされます。他の仮想環境やパッケージインストールによるシステムとは区別されます。

先に進んで、以前にクローンしたDjangoのコピーをインストールしてください:

$ python -m pip install -e /path/to/your/local/clone/django/
...\> py -m pip install -e \path\to\your\local\clone\django\

Djangoのインストールされたバージョンは、編集可能モードでインストールすることにより、ローカルコピーを指すようになります。これにより、加えた変更が即座に反映されるため、初めてのコントリビューションを書く際に非常に役立ちます。

ローカルに複製した Django でプロジェクトを作成する

ローカルの変更をDjangoプロジェクトでテストすることは有意義です。まず、新しい仮想環境を作成し、先ほどクローンしたDjangoのローカルコピーを編集可能モードでインストール し、Djangoのローカルコピーの外側に新しいDjangoプロジェクトを作成します。この設定により、新しいプロジェクト内でDjangoに加えた変更が即座に反映されるため、特にUIの変更をテストする場合、初めてのコントリビューションを書く際に非常に役立ちます。

Djangoプロジェクトの作り方については、 チュートリアル を参照してください。

最初に Django のテストスイートを実行する

Django に貢献する際には、コードの変更が Django の他の領域にバグを持ち込まないようにすることが非常に重要です。変更を行った後もDjangoが動作するかどうかを確認する方法の1つは、Djangoのテストスイートを実行することです。すべてのテストに合格していれば、あなたの変更が機能し、Django の他の部分を壊していないことを合理的に確認することができます。 Django のテストスイートを実行したことがない人は、事前に一度実行して出力に慣れておくと良いでしょう。

テストスイートを実行するする前に cd tests コマンドを使って Django の tests/ ディレクトリに移動し、実行することでテストの依存関係をインストールします。

$ python -m pip install -r requirements/py3.txt
...\> py -m pip install -r requirements\py3.txt

もしこのインストールの間にエラーが発生した場合は、システムが Python のうちの 1 つ以上の依存パッケージが見つからない可能性があります。失敗したパッケージのドキュメントを調べるか、発生したエラーメッセージをウェブで検索してください。

これでテストスイートを実行する準備が整いました:

$ ./runtests.py
...\> runtests.py 

さあ、座ってリラックスしてください。Django のテストスイート全体には何千ものテストがあり、コンピュータの速度にもよりますが、実行には少なくとも数分かかります。

Django のテストスイートを実行中に、各テストの完了時のステータスを表す一連の文字が表示されます。 E はテストにエラーが発生したことを表し、 F はテストのアサーションが失敗したことを表しています。これらは共にテスト失敗となります。xs はそれぞれ期待する失敗とスキップを表しています。ドットはテストの成功を表しています。

スキップされたテストは、テストを実行するために必要な外部ライブラリがインストールされていないことが原因です; 依存については Running all the tests を参照し、あなたの変更に関連するテストにする依存ライブラリがインストールしてください (このチュートリアルでは必要ありません)。いくつかのテストは、特定のデータベースバックエンドに固有であり、そのバックエンドでテストされない場合はスキップされます。 SQLite は、デフォルト設定のバックエンドです。別のバックエンドを使用してテストを実行するには、 Using another settings module を参照してください。

テストが終了するとテストが成功したか、失敗したかを知らせるメッセージが表示されます。まだ Django のコードに変更を加えていなければ、テストは全て パスするはずです 。もし失敗するかエラーが起こる場合は、これまでの全ステップを適切に実行してください。 Running the unit tests で、よりテストについて知れます。

最新の Django の main ブランチは常に安定しているとは限りません。 main バージョンで開発を行う場合、 Django の継続インテグレーションビルド をチェックしてください。これで、テストの失敗があなたのマシンだけのものか、 Django 公式のビルドによるものかが分かります。各ビルドについてのリンクをクリックすれば、 "Configuration Matrix" という、各 Python のバージョン、 DB バックエンドに対応したテストの失敗を閲覧できます。

注釈

このチュートリアルや、各チケットで作業する際は、SQLiteのテストで十分です。しかし、可能(か必要)な場合は、 他のデータベースでテストを実行する を参照してください。 UIを変更する場合は、 Seleniumのテストを実行する 必要があります。

取りかかる

このチュートリアルでは、ケーススタディとして「架空のチケット」を使って作業を進めます。以下はその架空の詳細です。

チケット #99999 -- トーストを焼くようにする

Django は、toast を返す関数 django.shortcuts.make_toast() を提供しなければなりません。

これよりこの機能と関連するテストを実装します。

ブランチを作る

変更を加える前に、チケット用に新しいブランチを作ります。

$ git checkout -b ticket_99999
...\> git checkout -b ticket_99999

ブランチ名は好きな名前で構いません。"ticket_99999" は一例です。新しいブランチ内で行ったすべての変更は、先ほどクローンしたコードのマスターコピーには影響しません。

チケットにテストを書く

ほとんどの場合、Djangoにコントリビューションが採用されるには、テストを含める必要があります。バグ修正のコントリビューションの場合、後で同じバグがDjangoに再導入されないようにするため、リグレッションテストを作成する必要があります。リグレッションテストは、バグが存在する間は失敗し、修正されたら成功するように記述してください。新機能を含むコントリビューションの場合、その新機能が正しく動作することを確認するためのテストを含める必要があります。この場合も、機能が存在しない場合は失敗し、実装されると成功するようにテストを作成してください。

新しいテストをコードの変更前に書くのは良い方法です。この開発スタイルはテスト駆動開発 test-driven development と呼ばれ、プロジェクト全体や個々の変更に適用できます。テストを書いたら、それを実行して、実際に失敗することを確認します(まだバグを修正していない、または機能を追加していないため)。新しいテストが失敗しない場合は、修正して失敗するようにする必要があります。なぜなら、バグが存在しているかどうかに関係なく成功するリグレッションテストは、そのバグが再発するのを防ぐのにあまり役立たないからです。

ハンズオンでの例題に移りましょう。

チケット #99999 に対するテストの実装

このチケットを解決するために、 make_toast() 関数に django.shortcuts モジュールに追加します。まずはこの関数を使うためのテストを書いて、関数の出力が正しいことを確認しましょう。

Djangoの tests/shortcuts/ フォルダへ移動して test_make_toast.py というファイルを新たに作ります。以下のコードを追加してください。

from django.shortcuts import make_toast
from django.test import SimpleTestCase


class MakeToastTests(SimpleTestCase):
    def test_make_toast(self):
        self.assertEqual(make_toast(), "toast")

このテストは make_toast()toast を返すかを確認します。

でもテストをするのはすこし難しそうです……

テストを書いたことがない場合は、最初は難しく見えるかもしれません。ですが実は、テストすることはプログラミングにおいて とても 重要なことです。ここではテストについて詳細に紹介します。

  • Django のための良いテストの書き方は テストを書いて実行する のドキュメントに記載されています。

  • Dive Into Python (Python初心者のための、オンラインの無料の本) には素晴らしい 初めてのユニットテスト という章があります。

  • Dive Into Python を読んだあと、もう少し情報が欲しい場合は、Python の unittest のドキュメントを参照してください。

新しいテストを走らせる

まだ django.shortcuts に変更を加えていないため、テストは失敗します。 shortcuts フォルダ内の全てのテストを実行して、どうなるか見てみましょう。 cd でDjangoの tests/ ディレクトリへと移動してから実行してください。

$ ./runtests.py shortcuts
...\> runtests.py shortcuts

テストが正しく実行されれば追加したテストメソッドに対して、こちらのエラーとともに1つテストが失敗しているはずです。

ImportError: cannot import name 'make_toast' from 'django.shortcuts'

テストがすべて通れば、上記した新しいテストを正しいフォルダ、クラスに追加したことを確認してください。

チケットにコードを書く

続いては make_toast() 関数を追加します。

django/ フォルダに移動して shortcuts.py ファイルを開きます。最下行に以下を追加します:

def make_toast():
    return "toast"

さて、先ほど書いたテストが成功したことを確認する必要があるので、追加したコードが正しく機能しているかどうかを確認できます。もう一度、Django の tests/ ディレクトリに移動して以下を実行します:

$ ./runtests.py shortcuts
...\> runtests.py shortcuts

テストはすべて成功するはずです。失敗した場合は、正しいファイルに対して正しく関数を追加しているかどうかを確認してください。

Django の テストスイートをもう一度走らせる

変更内容とテストが正しく動作していることを確認したら、Django全体のテストスイートを実行するのがおすすめです。これにより、あなたの変更がDjangoの他の部分にバグを引き起こしていないことを確認できます。テストスイートをすべて成功させることがコードの完全なバグ修正を保証するわけではありませんが、多くのバグや見逃されがちなリグレッションを特定するのに役立ちます。

Django の全てのテストスイートを走らせるには cd で Django の tests/ ディレクトリ移動して実行してください:

$ ./runtests.py
...\> runtests.py 

ドキュメントを書く

これは新たな機能です。したがってドキュメントを作る必要があります。ファイル docs/topics/http/shortcuts.txt を開いて、このファイルの最終行に以下を加えます。

``make_toast()``
================

.. function:: make_toast()

.. versionadded:: 2.2

Returns ``'toast'``.

この新機能は将来のリリースとともに、Django 次期バージョンのリリースノートにも含まれます。ファイル docs/releases/ の最新バージョン、このページの執筆時点では 2.2.txt のリリースノートを開き、"Minor Feature" ヘッダの下にノートを追記してください。

:mod:`django.shortcuts`
~~~~~~~~~~~~~~~~~~~~~~~

* The new :func:`django.shortcuts.make_toast` function returns ``'toast'``.

ドキュメントの書き方についてもっと知りたい場合は ドキュメントを書く を参照してください。ここでは、 versionadded の書き方についてや、 ドキュメントのコピーをローカルでビルドしてみて、 HTML をプレビューする方法などが書かれています。

変更点を確認する

次に、ブランチで行った変更を確認します。すべての変更をステージングしてコミットの準備をするには、次のコマンドを実行します:

$ git add --all
...\> git add --all

上により Django のカレントコピー (修正内容を含む) と、チュートリアル冒頭において行っていたチェックアウトリビジョンとの違いが表示されます。

$ git diff --cached
...\> git diff --cached

ページを進めるには上下キーを使います。

diff --git a/django/shortcuts.py b/django/shortcuts.py
index 7ab1df0e9d..8dde9e28d9 100644
--- a/django/shortcuts.py
+++ b/django/shortcuts.py
@@ -156,3 +156,7 @@ def resolve_url(to, *args, **kwargs):

     # Finally, fall back and assume it's a URL
     return to
+
+
+def make_toast():
+    return 'toast'
diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt
index 7d85d30c4a..81518187b3 100644
--- a/docs/releases/2.2.txt
+++ b/docs/releases/2.2.txt
@@ -40,6 +40,11 @@ database constraints. Constraints are added to models using the
 Minor features
 --------------

+:mod:`django.shortcuts`
+~~~~~~~~~~~~~~~~~~~~~~~
+
+* The new :func:`django.shortcuts.make_toast` function returns ``'toast'``.
+
 :mod:`django.contrib.admin`
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~

diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt
index 7b3a3a2c00..711bf6bb6d 100644
--- a/docs/topics/http/shortcuts.txt
+++ b/docs/topics/http/shortcuts.txt
@@ -271,3 +271,12 @@ This example is equivalent to::
         my_objects = list(MyModel.objects.filter(published=True))
         if not my_objects:
             raise Http404("No MyModel matches the given query.")
+
+``make_toast()``
+================
+
+.. function:: make_toast()
+
+.. versionadded:: 2.2
+
+Returns ``'toast'``.
diff --git a/tests/shortcuts/test_make_toast.py b/tests/shortcuts/test_make_toast.py
new file mode 100644
index 0000000000..6f4c627b6e
--- /dev/null
+++ b/tests/shortcuts/test_make_toast.py
@@ -0,0 +1,7 @@
+from django.shortcuts import make_toast
+from django.test import SimpleTestCase
+
+
+class MakeToastTests(SimpleTestCase):
+    def test_make_toast(self):
+        self.assertEqual(make_toast(), 'toast')

変更内容のプレビューが終わったら、q キーを押してコマンドラインに戻ります。差分が問題なさそうであれば、変更をコミットする準備が整いました。

変更をコミットする

変更点をコミットするには、次のコマンドを実行します。

$ git commit
...\> git commit

すると、コミットメッセージを入力するためのテキストエディタが開きます。 コミットメッセージガイドライン に従って、次のようにメッセージを入力します。

Fixed #99999 -- Added a shortcut function to make toast.

コミットのプッシュとプルリクエストの作成

変更をコミットした後、それをGitHubのフォークに送信します(ブランチ名が異なる場合は、"ticket_99999" をその名前に置き換えてください):

$ git push origin ticket_99999
...\> git push origin ticket_99999

プルリクエストは Django の GitHub ページ から作成できます。"Your recently pushed branches" の下にあなたのブランチが表示されているはずです。その下の "Compare & pull request" ボタンをクリックします。

このチュートリアルでは実行してはいけませんが、次のページで変更のプレビューが表示されたら、「Create pull request」ボタンをクリックします。

次のステップ

おめでとうございます! これで Django へのプルリクエストの作成方法を学ぶことができました。応用テクニックについて詳しくは Working with Git and GitHub を読んでください。

これで、Django のコードベースを改良する手助けができるようになりました。

新しいコントリビューターのための追加情報

Djangoへのコントリビューションに本格的に取り組む前に、確認しておくべきいくつかの追加情報があります。以下を参考にしてください:

  • Djangoの チケットの取得とプルリクエストの送信 に関するドキュメントを必ず読んでください。このドキュメントでは、Tracのエチケット、チケットの取得方法、コードとドキュメントのコーディングスタイルの期待事項、その他の重要な詳細について説明しています。

  • Django への初めてのコントリビューターは 初めてのコントリビューターへのドキュメント を読んでください。Django に初めて協力する人たちへの良いアドバイスがあります。

  • 貢献について、より多くの情報を知りたいなら、 貢献についての Django のドキュメント を参照してください。そこにはたくさん有用な情報がありまし、質問があれば、このドキュメントが1番役に立ちます。

実際にチケットを探してみましょう

これらの情報に目を通したら、自分で取り組むチケットを見つける準備が整います。「easy pickings」のラベルが付いたチケットに特に注目してください。これらのチケットは、内容が比較的簡単で、初めてのコントリビューションに最適です。Djangoへのコントリビューションに慣れてきたら、より難しく複雑なチケットにも取り組み始めることができます。

すぐに始めたい場合(誰もあなたを責めません!)、easy tickets without a branch や、easy tickets that have branches which need improvement のリストを確認してみてください。テストを書くことに慣れている場合は、easy tickets that need tests のリストも参考にするとよいでしょう。チケットを取得する際は、チケットの取得とブランチの送信 に記載されているガイドラインを必ず遵守してください。

プルリクエストを作ったあとは?

チケットにブランチが作成された後は、別の人によるレビューが必要です。プルリクエストを提出した後は、チケットのメタデータを更新して、フラグを "has patch" や "doesn't need tests" などに設定してください。これにより、他の人がレビューのために見つけやすくなります。貢献することは、必ずしもコードをゼロから書くことだけではありません。オープンなプルリクエストをレビューすることも非常に有益な貢献です。詳細については、 チケットをトリアージする を参照してください。

Back to Top