Написание вашего первого патча для Django
Введение
Хотите внести свой вклад в сообщество? Возможно, вы обнаружили ошибку в Django, которую хотели бы исправить, или, может быть, хотите добавить небольшую функцию.
Внесение изменений в сам Django — лучший способ увидеть, как ваши проблемы решаются. Это может показаться сложным на первый взгляд, но это хорошо протоптанный путь с документацией, инструментами и сообществом, которое поддержит вас. Мы пройдем вас через весь процесс, чтобы вы могли учиться на примерах.
Для кого этот учебник?
См. также
Если вы ищете справочник по деталям внесения вклада в код, обратитесь к документации по написанию кода.
Для этого учебника предполагается, что вы имеете хотя бы базовое понимание работы Django. Это означает, что вы должны уметь проходить существующие учебники по созданию вашего первого приложения Django. Кроме того, вы должны хорошо понимать сам Python. Но если нет, Dive Into Python — фантастическая (и бесплатная) онлайн-книга для начинающих программистов Python.
Те из вас, кто не знаком с системами управления версиями и Trac, обнаружат, что этот учебник и его ссылки содержат достаточно информации для начала работы. Тем не менее, вам, вероятно, захочется почитать больше об этих инструментах, если вы планируете регулярно участвовать в разработке Django.
В основном же этот учебник пытается объяснить как можно больше, чтобы он был полезен для самого широкого круга пользователей.
Где получить помощь:
Если у вас возникли трудности с прохождением этого учебника, отправьте сообщение на django-developers или зайдите в #django-dev на irc.libera.chat, чтобы поговорить с другими пользователями Django, которые могут помочь.
Что охватывает этот учебник?
Мы пройдем вас через внесение патча в Django в первый раз. По окончании этого учебника вы должны получить базовое понимание как инструментов, так и используемых процессов. В частности, мы будем охватывать следующее:
- Установка Git.
- Скачивание копии разрабатываемой версии Django.
- Запуск тестового набора Django.
- Написание теста для вашего патча.
- Написание кода для вашего патча.
- Тестирование вашего патча.
- Отправка запроса на объединение.
- Где найти дополнительную информацию.
После завершения учебника вы можете ознакомиться с остальной частью документации Django по внесению вклада. Она содержит много ценной информации и является обязательной для прочтения для всех, кто хотел бы стать постоянным участником разработки Django. Если у вас есть вопросы, ответы на них, скорее всего, там.
Требуется Python 3!
Текущая версия Django не поддерживает Python 2.7. Скачайте Python 3 со страницы загрузки Python или с помощью менеджера пакетов вашей операционной системы.
Для пользователей Windows
См. установку Python в документации по Windows для получения дополнительной информации.
Кодекс поведения
В качестве участника вы можете помочь нам сохранить сообщество Django открытым и инклюзивным. Прочитайте и следуйте нашему Кодексу поведения.
Установка Git
Для этого учебника вам понадобится установленный Git для скачивания текущей разрабатываемой версии Django и для создания файлов патчей для внесенных изменений.
Чтобы проверить, установлен ли Git, введите git в командной строке. Если вы получите сообщения о том, что эта команда не найдена, вам нужно будет загрузить и установить ее, см. страницу загрузки Git.
Если вы не очень знакомы с Git, вы всегда можете узнать больше о его командах (после установки), набрав git help в командной строке.
Получение копии разрабатываемой версии Django
Первый шаг к внесению изменений в Django — получить копию исходного кода. Сначала создайте форк Django на GitHub. Затем из командной строки используйте команду cd для перехода в каталог, где вы хотите разместить локальную копию Django.
Загрузите репозиторий исходного кода Django с помощью следующей команды:
$ git clone https://github.com/YourGitHubName/django.git
...\> git clone https://github.com/YourGitHubName/django.git
Подключение с низкой пропускной способностью?
Вы можете добавить аргумент --depth 1 к git clone, чтобы пропустить загрузку всей истории коммитов Django, что уменьшит передачу данных с ~250 МБ до ~70 МБ.
Теперь, когда у вас есть локальная копия 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 в вашем новом проекте, что очень полезно при написании вашего первого патча.
Запуск тестового набора Django в первый раз
При внесении изменений в Django очень важно, чтобы ваши изменения не вносили ошибки в другие области Django. Один из способов проверить, работает ли Django после внесения изменений, — это запустить тестовый набор Django. Если все тесты пройдут, вы можете быть достаточно уверены, что ваши изменения работают и не сломали другие части Django. Если вы никогда раньше не запускали тестовый набор Django, рекомендуется запустить его один раз предварительно, чтобы ознакомиться с его выводом.
Перед запуском тестового набора перейдите в каталог Django tests/ с помощью команды cd tests и установите зависимости тестов, выполнив:
$ python -m pip install -r requirements/py3.txt
...\> py -m pip install -r requirements\py3.txt
Если во время установки возникнет ошибка, возможно, на вашем компьютере отсутствует зависимость для одного или нескольких пакетов Python. Обратитесь к документации пакета, который вызывает ошибку, или выполните поиск в Интернете с сообщением об ошибке.
Теперь мы готовы запустить тестовый набор. Если вы используете GNU/Linux, macOS или другую разновидность Unix, выполните:
$ ./runtests.py
...\> runtests.py
Теперь отдохните. Полный тестовый набор Django содержит тысячи тестов, и его выполнение занимает не менее нескольких минут, в зависимости от скорости вашего компьютера.
Во время работы тестового набора Django вы увидите поток символов, представляющих состояние каждого теста по мере его завершения. E указывает, что во время теста произошла ошибка, а F указывает, что утверждения теста не сработали. Оба этих случая считаются сбоями тестов. Тем временем x и s указывают на ожидаемые ошибки и пропущенные тесты соответственно. Точки указывают на прохождение тестов.
Пропущенные тесты обычно связаны с отсутствием внешних библиотек, необходимых для запуска теста; см. Запуск всех тестов для списка зависимостей и убедитесь, что установлены любые, относящиеся к изменениям, которые вы вносите (нам они не понадобятся в этом учебнике). Некоторые тесты специфичны для определенного бэкенда базы данных и будут пропущены, если вы не тестируете с этим бэкендом. SQLite — это бэкенд базы данных для стандартных настроек. Чтобы запустить тесты с другим бэкендом, см. Использование другого модуля настроек.
END_OF_DOCUMENT_MARKERПосле завершения тестов вы должны увидеть сообщение, информирующее вас о том, пройден ли набор тестов или нет. Поскольку вы еще не внесли никаких изменений в код Django, весь набор тестов должен пройти. Если у вас возникли сбои или ошибки, убедитесь, что вы правильно выполнили все предыдущие шаги. См. Запуск модульных тестов для получения дополнительной информации.
Обратите внимание, что последняя ветка Django «main» не всегда может быть стабильной. При разработке на «main» вы можете проверить непрерывную интеграцию Django, чтобы определить, являются ли сбои специфичными для вашей машины или также присутствуют в официальных сборках Django. Если вы нажмете, чтобы просмотреть определенную сборку, вы сможете увидеть «Матрицу конфигурации», которая показывает сбои, разбитые по версиям Python и базам данных.
Примечание
Для этого учебника и билета, над которым мы работаем, тестирование против SQLite достаточно, однако, возможно (и иногда необходимо) запустить тесты с использованием другой базы данных.
Работа с функцией
В этом руководстве мы будем работать с «фиктивным билетом» в качестве примера. Вот вымышленные подробности:
Билет #99999 – Разрешить изготовление тостов
Django должен предоставить функцию django.shortcuts.make_toast(), которая возвращает 'toast'.
Теперь мы реализуем эту функцию и соответствующие тесты.
Создание ветки для вашего исправления
Перед внесением каких-либо изменений создайте новую ветку для билета:
$ git checkout -b ticket_99999
...\> git checkout -b ticket_99999
Вы можете выбрать любое имя для ветки, «ticket_99999» — это пример. Все изменения, внесенные в эту ветку, будут специфичными для билета и не повлияют на основную копию кода, которую мы клонировали ранее.
Написание тестов для вашего билета
В большинстве случаев для принятия исправления в Django оно должно включать тесты. Для исправлений ошибок это означает написание регрессионного теста, чтобы гарантировать, что ошибка никогда не будет повторно введена в Django в будущем. Регрессионный тест должен быть написан таким образом, чтобы он завершался неудачей, пока ошибка существует, и завершался успешно после того, как ошибка была исправлена. Для исправлений, содержащих новые функции, вам необходимо включить тесты, которые гарантируют, что новые функции работают правильно. Они также должны завершаться неудачей, когда новая функция отсутствует, а затем завершаться успешно после её реализации.
Хороший способ сделать это — написать новые тесты сначала, прежде чем вносить какие-либо изменения в код. Такой стиль разработки называется разработкой, основанной на тестах, и его можно применять как к целым проектам, так и к отдельным исправлениям. После написания тестов, вы затем запускаете их, чтобы убедиться, что они действительно завершаются неудачей (поскольку вы еще не исправили эту ошибку или не добавили эту функцию). Если новые тесты не завершаются неудачей, вам нужно исправить их, чтобы они завершались неудачей. В конце концов, регрессионный тест, который проходит независимо от наличия ошибки, не очень полезен для предотвращения повторного возникновения этой ошибки.
Теперь для нашего практического примера.
Написание теста для билета #99999
Для разрешения этого билета мы добавим функцию make_toast() в модуль django.shortcuts. Сначала мы напишем тест, который попытается использовать функцию и проверит, что её вывод выглядит правильно.
Перейдите в папку tests/shortcuts/ Django и создайте новый файл 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) содержит отличное введение в модульное тестирование.
- После прочтения этих материалов, если вам нужно что-то посерьезнее, всегда есть документация Python по
unittest.
Запуск нового теста
Поскольку мы еще не внесли никаких изменений в django.shortcuts, наш тест должен завершиться неудачей. Давайте запустим все тесты в папке shortcuts, чтобы убедиться, что это действительно происходит. Перейдите в каталог Django tests/ и выполните:
$ ./runtests.py shortcuts
...\> runtests.py shortcuts
Если тесты были запущены правильно, вы должны увидеть одну неудачу, соответствующую методу теста, который мы добавили, с этой ошибкой:
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, перейдите в каталог 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. Добавьте примечание под заголовком «Незначительные функции»:
: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. Вы увидите свою ветку в разделе «Ваши недавно отправленные ветки». Нажмите «Сравнить и создать запрос на вытягивание» рядом с ней.
Пожалуйста, не делайте этого для этого учебника, но на следующей странице, которая отображает предварительный просмотр исправления, вы бы нажали «Создать запрос на вытягивание».
Следующие шаги
Поздравляем, вы узнали, как создать запрос на вытягивание для Django! Подробности более продвинутых техник, которые могут понадобиться, находятся в Работа с Git и GitHub.
Теперь вы можете использовать эти навыки, чтобы помочь улучшить базу кода Django.
Дополнительная информация для новых участников
Прежде чем углубляться в написание исправлений для Django, ознакомьтесь с дополнительной информацией о сотрудничестве:
- Вы должны обязательно прочитать документацию Django по заявке на тикеты и отправке патчей. В ней описаны правила этикета Trac, как заявлять тикеты на себя, ожидаемый стиль кодирования патчей и многие другие важные детали.
- Первые участники должны также прочитать документацию Django для новых участников. В ней есть много полезных советов для тех из нас, кто только начинает помогать с Django.
- После этого, если вы все еще хотите узнать больше о сотрудничестве, вы всегда можете просмотреть остальную часть документации Django по участию. Она содержит массу полезной информации и должна быть вашим основным источником для ответа на любые ваши вопросы.
Поиск вашего первого реального тикета
После ознакомления с этой информацией вы будете готовы найти тикет, чтобы написать для него патч. Обратите особое внимание на тикеты с критерием «легкие». Такие тикеты часто намного проще по своей природе и отлично подходят для новых участников. После того как вы освоитесь с участием в Django, вы можете перейти к написанию патчей для более сложных и запутанных тикетов.
Если вы хотите сразу начать (и никто вас не осудит!), попробуйте посмотреть список легких тикетов, которым нужны патчи и легких тикетов, патчи которых нуждаются в улучшении. Если вы знакомы с написанием тестов, вы также можете посмотреть список легких тикетов, которым нужны тесты. Не забудьте следовать рекомендациям по заявке на тикеты, которые были упомянуты в ссылке на документацию Django по заявке на тикеты и отправке патчей.
Что делать после создания запроса на объединение?
После того, как к тикету прикреплен патч, его необходимо проверить. После отправки запроса на объединение обновите метаданные тикета, установив флаги, указывающие на наличие патча, отсутствие необходимости в тестах и т. д., чтобы другие могли его найти для проверки. Участие не всегда означает написание патча с нуля. Проверка существующих патчей также является очень полезным вкладом. Подробнее об этом см. в Обработке тикетов.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/4.2/intro/contributing/