{"title":"编写你的第一个 Django 补丁","version":"3.0","locale":"zh-hans","docname":"intro/contributing","url":"/zh-hans/3.0/intro/contributing/","canonical":"https://djangodocs.dev/zh-hans/3.0/intro/contributing/","summary":"介绍 Link to this heading # 想为 Django 社区做一点贡献？也许是你发现了一个想修复的 bug，或者想添加一个新的功能。 回报 Django…","html":"<h1>编写你的第一个 Django 补丁<a class=\"heading-anchor\" href=\"#writing-your-first-patch-for-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<section id=\"introduction\">\n<h2>介绍<a class=\"heading-anchor\" href=\"#introduction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>想为 Django 社区做一点贡献？也许是你发现了一个想修复的 bug，或者想添加一个新的功能。</p>\n<p>回报 Django 这件事本身就是使你的顾虑得到解决的最好方式。一开始这可能会使你怯步，但这是一条有文档、工具和社区支持的成功之路。整个过程中我们会一步一步为你解说，所以你可以通过例子学习。</p>\n<section id=\"who-s-this-tutorial-for\">\n<h3>这个教程适合谁？<a class=\"heading-anchor\" href=\"#who-s-this-tutorial-for\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition admonition-seealso\">\n<p class=\"admonition-title\">See also</p>\n<p>如果你正在寻找一个关于如何提交补丁的说明文档，请查看 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">Submitting patches</span></a>。</p>\n</aside>\n<p>使用教程前，我们希望你至少对于 Django 的运行方式有一定的认识。 这意味着你可以很容易地通读 <a class=\"reference internal\" href=\"/zh-hans/3.0/intro/tutorial01/\"><span class=\"doc\">编写第一个 Django 应用</span></a>。 除此之外，你应该对于 Python 有很好的理解。 如果不太熟悉 Python，我们为您推荐  <a href=\"#id11\"><span class=\"problematic\" id=\"id12\">`Dive Into Python`__</span></a> 对于初学Python的程序员来说这是一本很棒（而且免费）的在线电子书。</p>\n<p>那些不熟悉版本控制系统及缺陷跟踪的朋友可以查看这个教程，这个链接包含了足够的信息。如果你打算定期地为 Django 做贡献，你可能期望阅读更多关于这些不同工具的资料。</p>\n<p>当然对于此教程中的大部分内容，Django 会尽可能做出解释以帮助广大的读者。</p>\n<aside class=\"admonition-where-to-get-help admonition\">\n<p class=\"admonition-title\">从哪里获得帮助：</p>\n<p>如果你在使用本教程时遇到困难, 你可以发信息给 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a> 中的人或登陆 <a href=\"#id11\"><span class=\"problematic\" id=\"id13\">`#django-dev on irc.freenode.net`__</span></a> 向其他 Django 使用者寻求帮助。</p>\n</aside>\n</section>\n<section id=\"what-does-this-tutorial-cover\">\n<h3>这个指南涵盖哪些内容？<a class=\"heading-anchor\" href=\"#what-does-this-tutorial-cover\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>我们将指导你贡献你的第一个 Django 补丁，在本教程完毕时，你将对相关工具及流程有一个基本的认识。特别的，我们将覆盖以下内容：</p>\n<ul class=\"simple\">\n<li><p>安装 Git。</p></li>\n<li><p>下载一份Django开发版的拷贝。</p></li>\n<li><p>运行 Django 的测试套件。</p></li>\n<li><p>为你的补丁写一个测试。</p></li>\n<li><p>为你的补丁编写代码。</p></li>\n<li><p>测试你的补丁。</p></li>\n<li><p>提交一个 pull request（PR）。</p></li>\n<li><p>在哪里查找更多的信息。</p></li>\n</ul>\n<p>一旦你完成了这份教程，你可以浏览 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/\"><span class=\"doc\">Django 贡献文档</span></a> 的剩余部分。它包含了大量信息。任何想成为 Django 的正式贡献者的人都必须阅读它。如果你有问题，它也许会给你答案。</p>\n<aside class=\"admonition-python-3-required admonition\">\n<p class=\"admonition-title\">必须Python 3！</p>\n<p>目前的 Django 版本不再支持 Python 2.7。你可以在 <a class=\"reference external\" href=\"https://www.python.org/downloads/\">Python 下载页</a> 或通过操作系统的包管理器下载 Python 3。</p>\n</aside>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">对于 Windows 用户</p>\n<p>See <a class=\"reference internal\" href=\"/zh-hans/3.0/howto/windows/#install-python-windows\"><span class=\"std std-ref\">安装Python</span></a> on Windows docs for additional guidance.</p>\n</aside>\n</section>\n</section>\n<section id=\"code-of-conduct\">\n<h2>代码规范<a class=\"heading-anchor\" href=\"#code-of-conduct\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>作为一个贡献者, 你可以帮助我们保持 Django 的社区开放性和包容性。请仔细阅读并遵守我们的 <a class=\"reference external\" href=\"https://www.djangoproject.com/conduct/\">行为守则</a>。</p>\n</section>\n<section id=\"installing-git\">\n<h2>安装Git<a class=\"heading-anchor\" href=\"#installing-git\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>在本教程中，你需要安装好 Git，用 Git 下载 Django 的最新开发版本并且为你的修改生成补丁文件。</p>\n<p>要检查你是否已经安装 Git，命令行输入 <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span></code>。如果提示这个命令无法找到，你必须下载并安装它，参考 <a href=\"#id11\"><span class=\"problematic\" id=\"id14\">`Git's download page`__</span></a> 。</p>\n<p>如果你还不熟悉 Git, 你可以在命令行下输入 <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span> <span class=\"pre\">help</span></code>  了解更多关于 Git 命令的使用方法 (确保已安装)</p>\n</section>\n<section id=\"getting-a-copy-of-django-s-development-version\">\n<h2>获得一个 Django 开发版本的副本<a class=\"heading-anchor\" href=\"#getting-a-copy-of-django-s-development-version\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>为 Django 做贡献的第一步就是获取源代码副本。首先， fork Github 上的 Django 项目 &lt;https://github.com/django/django/fork&gt;。接下来，在命令行中，使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> 命令切换至某个你想存放 Django 源码的目录。</p>\n<p>使用下面的命令来下载 Django 的源码库：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-0-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>clone<span class=\"w\"> </span>https://github.com/YourGitHubName/django.git\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-0-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> git clone https://github.com/YourGitHubName/django.git\n</code></pre></div></div></div>\n<aside class=\"admonition-low-bandwidth-connection admonition\">\n<p class=\"admonition-title\">低速宽带连接？</p>\n<p>你可以在用命令 <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span> <span class=\"pre\">clone</span></code> 下载仓库的时候加上参数 <code class=\"docutils literal notranslate\"><span class=\"pre\">--depth</span> <span class=\"pre\">1</span></code> 来跳过 Django 的提交历史，这大约能把下载大小从250MB减少到70MB</p>\n</aside>\n<p>你现在已经将Django拷贝到本地，可以像安装其他软件包一样使用 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>pip``进行安装。 最便捷的方式是通过  <em>virtual environment</em>， 这是 Python 的一个内置特性，它可以让你在一个目录中保持独立的软件包环境而不影响其他的项目。</p>\n<p>将你的虚拟环境都放在一个位置是明智的做法，例如将它们放置在你主目录下的 <code class=\"docutils literal notranslate\"><span class=\"pre\">.virtualenvs/</span></code> 中。</p>\n<p>通过运行以下命令创建一个虚拟环境：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-1-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python3<span class=\"w\"> </span>-m<span class=\"w\"> </span>venv<span class=\"w\"> </span>~/.virtualenvs/djangodev\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-1-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m venv <span class=\"nv\">%HOMEPATH%</span>\\.virtualenvs\\djangodev\n</code></pre></div></div></div>\n<p>该路径就是保存这个新的虚拟运行环境的地方。</p>\n<p>设置虚拟环境的最后一步是激活它；</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span><span class=\"nb\">source</span><span class=\"w\"> </span>~/.virtualenvs/djangodev/bin/activate\n</code></pre></div>\n<p>如果 <code class=\"docutils literal notranslate\"><span class=\"pre\">source</span></code> 命令不可用，你可以试试：</p>\n<div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>.<span class=\"w\"> </span>~/.virtualenvs/djangodev/bin/activate\n</code></pre></div>\n<p>每当打开一个新的终端窗口，都必须先激活虚拟环境。</p>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">对于 Windows 用户</p>\n<p>在Windows下采用如下命令进行激活虚拟环境：</p>\n<div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows code\"><code><span class=\"gp\">...\\&gt;</span> <span class=\"nv\">%HOMEPATH%</span>\\.virtualenvs\\djangodev\\Scripts\\activate.bat\n</code></pre></div>\n</aside>\n<p>当前激活的虚拟环境的名称会被展示在命令行，这可以让你搞清楚你正在使用哪一个虚拟环境。你通过 <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code> 安装的任何软件包如果在安装时显示了该名称，则都会被安装到该虚拟环境中，而且这些软件包不会影响到其他虚拟环境，也不会与其他系统级的软件包发生冲突。</p>\n<p id=\"intro-contributing-install-local-copy\">下一步安装之前克隆的 Django 副本：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-2-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>-m<span class=\"w\"> </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>-e<span class=\"w\"> </span>/path/to/your/local/clone/django/\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-2-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m pip install -e \\path\\to\\your\\local\\clone\\django\\\n</code></pre></div></div></div>\n<p>在可编辑的模式下，安装的 Django 版本就是你本地副本的版本。你将立刻见到任何你对它的修改，这对你编写第一个补丁很有帮助。</p>\n<section id=\"creating-projects-with-a-local-copy-of-django\">\n<h3>使用 Django 本地副本创建项目<a class=\"heading-anchor\" href=\"#creating-projects-with-a-local-copy-of-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>这对你测试本地Django项目发生了那些变化很有帮助。首先，你需要创建一个新的虚拟环境， <a class=\"reference internal\" href=\"#intro-contributing-install-local-copy\"><span class=\"std std-ref\">在可编辑模式下安装之前克隆的Django本地副本</span></a>, 接着在你本地Django副本之外创建一个新的Django项目。 在你的新项目中，一旦你改动任何文件，你都会立刻看到相关信息，这对你编写第一个补丁是很有帮助的。</p>\n</section>\n</section>\n<section id=\"running-django-s-test-suite-for-the-first-time\">\n<h2>首先运行 Django 的测试套件<a class=\"heading-anchor\" href=\"#running-django-s-test-suite-for-the-first-time\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>当你贡献代码给 Django 的时候，你修改的代码千万不要给其它部分引入新的 bug。 有个办法可以在你更改代码之后检查 Django 是否能正常工作，就是运行 Django 的测试套件。如果所有的测试用例都通过，你就有理由相信你的改动完全没有破坏 Django。如果你从来没有运行过 Django 的测试套件，那么比较好的做法是事先运行一遍，熟悉下正常情况下应该输出什么结果。</p>\n<p>运行测试套件之前，先 <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> 进入 Django 的 <code class=\"docutils literal notranslate\"><span class=\"pre\">test/</span></code> 目录，安装其依赖，运行：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-3-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>python<span class=\"w\"> </span>-m<span class=\"w\"> </span>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>-r<span class=\"w\"> </span>requirements/py3.txt\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-3-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> py -m pip install -r requirements\\py3.txt\n</code></pre></div></div></div>\n<p>如果安装过程中发生了错误，可能是你的系统缺少一个或多个 Python 依赖包。请参考安装失败的包的文档或者在网上搜索提示的错误信息。</p>\n<p>现在你可以运行测试套件。如果你用的是 GNU/Linux， macOS 或者其它类 Unix 系统，运行：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-4-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-4-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> runtests.py \n</code></pre></div></div></div>\n<p>接下来，需要耐心等待一段时间，因为 Django 的整个测试套件有数千个测试项，一般需要几分钟的时间才能运行结束。</p>\n<p>当Django的测试套件被执行时，您将看到一个代表测试运行状态的字符流。 其中字符 <code class=\"docutils literal notranslate\"><span class=\"pre\">E</span></code> 表示测试中出现异常， <code class=\"docutils literal notranslate\"><span class=\"pre\">F</span></code> 表示测试中的一个断言失败，这两种情况都被认为测试结果失败。而 <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> 和 <code class=\"docutils literal notranslate\"><span class=\"pre\">s</span></code> 分别表示与期望结果不同和跳过测试，逗点则表示测试被通过了。</p>\n<p>缺失外部依赖库通常会导致测试被跳过；查看 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/unit-tests/#running-unit-tests-dependencies\"><span class=\"std std-ref\">Running all the tests</span></a> 获取依赖库列表，如果你修改了测试代码，请同时安装相关依赖库（本教程无需额外依赖库）。某些测试使用了特定的数据库后端，如果当前测试设置并未使用此数据库后端，那么这些相关的测试也会被跳过。SQLite 是默认的数据库后端。如果想使用其他后端进行测试，查看 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">Using another settings module</span></a>。</p>\n<p>代码测试集当测试执行完毕后，得到反馈信息显示测试已通过，或者测试失败。 因为还没有对 Django 的代码做任何修改, 所有的测试集 <strong>应该</strong> 测试通过. 如果测试失败或出现错误，回头确认以上执行操作是否正确. 查看 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/unit-tests/#running-unit-tests\"><span class=\"std std-ref\">Running the unit tests</span></a> 获取更多信息。</p>\n<p>注意最新版本 Django 分支不总是稳定的。当在分支上开发时，你可以查看代码持续集成构建页面的信息 来判断测试错误只在你指定的电脑上发生，还是官方版本中也存在该错误。如果点击某个构建信息，可以通过 &quot;Configuration Matrix&quot; 查看错误发生时 Python 以及后端数据库的信息。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>在本教程以及处理工单所用分支中，测试使用数据库 SQLite 即可，然而在某些情况下需要（有时需要） ，参考 :ref:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>run the tests using a different database <a href=\"#id3\"><span class=\"problematic\" id=\"id4\">`</span></a>。</p>\n</aside>\n</section>\n<section id=\"working-on-a-feature\">\n<h2>尝试搞定一项新功能<a class=\"heading-anchor\" href=\"#working-on-a-feature\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>这次教程中，我们将学习去完成一个名叫 &quot;fake ticket&quot; 的例子。下面是关于这个例子的大体构想:</p>\n<aside class=\"admonition-ticket-99999-allow-making-toast admonition\">\n<p class=\"admonition-title\">Ticket #99999 -- 允许发表祝辞</p>\n<p>Djando中需要声明一个函数django.shortcuts.make_toast()，它的返回值为'toast'。</p>\n</aside>\n<p>我们现在来实现这个新功能并且做一下相关的测试。</p>\n</section>\n<section id=\"creating-a-branch-for-your-patch\">\n<h2>为你的补丁创建一个分支<a class=\"heading-anchor\" href=\"#creating-a-branch-for-your-patch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>在做出任何修改之前，为你的工单创建一个分支：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-5-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>checkout<span class=\"w\"> </span>-b<span class=\"w\"> </span>ticket_99999\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-5-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> git checkout -b ticket_99999\n</code></pre></div></div></div>\n<p>你可以选择任意你想要的分支名，ticket_99999只是一个例子。你在该分支上做出的所有更改，将只会针对该分支即ticket_99999产生影响，而不会影响到我们早先克隆的原始代码。</p>\n</section>\n<section id=\"writing-some-tests-for-your-ticket\">\n<h2>为你的工单写一些测试用例<a class=\"heading-anchor\" href=\"#writing-some-tests-for-your-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>大多数情况下，Django 的补丁必需包含测试。Bug 修复补丁的测试是一个回归测试，确保该 Bug 不会再次在 Django 中出现。该测试应该在 Bug 存在时测试失败，在 Bug 已经修复后通过测试。新功能补丁的测试必须验证新功能是否正常运行。新功能的测试将在功能正常时通过测试，功能未执行时测试失败。</p>\n<p>最好的方式是在修改代码之前写测试单元代码。这种开发风格叫做 <a href=\"#id11\"><span class=\"problematic\" id=\"id15\">`test-driven development`__</span></a> 被应用在项目开发和单一补丁开发过程中。单元测试编写完毕后，执行单元测试，此时测试失败（因为目前还没有修复 bug 或添加新功能），如果测试成功通过，你需要重新修改单元测试保证测试失败。因为单元测试并不能阻止 bug 发生。</p>\n<p>现在看我们的操作示例。</p>\n<section id=\"writing-a-test-for-ticket-99999\">\n<h3>为工单 #99999 写测试<a class=\"heading-anchor\" href=\"#writing-a-test-for-ticket-99999\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>为了解决这次的工单问题，我们将在最上层的 django 模块中添加一个函数 <code class=\"docutils literal notranslate\"><span class=\"pre\">make_toast()</span></code>。首先我们来写一个测试用例，用于测试该函数，并且验证一下它的输出项是否正确。</p>\n<p>前往Django的 <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/shortcuts/</span></code> 文件夹，创建一个名为 <code class=\"docutils literal notranslate\"><span class=\"pre\">test_make_toast.py</span></code> 的新文件。添加如下代码:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">make_toast</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.test</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">SimpleTestCase</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MakeToastTests</span><span class=\"p\">(</span><span class=\"n\">SimpleTestCase</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">test_make_toast</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">assertEqual</span><span class=\"p\">(</span><span class=\"n\">make_toast</span><span class=\"p\">(),</span> <span class=\"s1\">&#39;toast&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>上述测试是用来检测 <code class=\"docutils literal notranslate\"><span class=\"pre\">make_toast()</span></code> 函数是否会返回 <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>'toast'` <a href=\"#id3\"><span class=\"problematic\" id=\"id4\">`</span></a>的。</p>\n<aside class=\"admonition-but-this-testing-thing-looks-kinda-hard admonition\">\n<p class=\"admonition-title\">但这种测试看起来有点困难……</p>\n<p>如果你之前从未处理过测试，那他们看起来会有点难以编写。幸运的是，测试是一个计算机编程中 <em>非常</em> 大的一个主题，所以这里有大量的相关资料：</p>\n<ul class=\"simple\">\n<li><p>浏览 <a class=\"reference internal\" href=\"/zh-hans/3.0/topics/testing/overview/\"><span class=\"doc\">编写并运行测试</span></a> 大致看一下如何在 Django 中编写测试。</p></li>\n<li><p>深入理解 Python（一本针对 Python 初学者的免费在线书籍），包含了不错的 <a href=\"#id11\"><span class=\"problematic\" id=\"id16\">`introduction to Unit Testing`__</span></a>。</p></li>\n<li><p>读到这里，你还想深入了解的话，可以查看 Python <a class=\"reference external\" href=\"https://docs.python.org/3/library/unittest.html#module-unittest\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">unittest</span></code></a>。</p></li>\n</ul>\n</aside>\n</section>\n<section id=\"running-your-new-test\">\n<h3>运行你的新测试<a class=\"heading-anchor\" href=\"#running-your-new-test\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>由于我们还没有对 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.shortcuts</span></code> 进行任何修改，这次测试将会失败。现在让我们来运行一下 <code class=\"docutils literal notranslate\"><span class=\"pre\">shortcuts</span></code> 目录中的所有测试，以便确定它们真的都会产生失败的结果。使用 <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> 命令进入Django的 <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> 文件夹，然后运行:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-6-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py<span class=\"w\"> </span>shortcuts\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-6-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> runtests.py shortcuts\n</code></pre></div></div></div>\n<p>如果测试被正确执行，一个该测试方法所对应的错误将会呈现给你:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"ne\">ImportError</span><span class=\"p\">:</span> <span class=\"n\">cannot</span> <span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">name</span> <span class=\"s1\">&#39;make_toast&#39;</span> <span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"s1\">&#39;django.shortcuts&#39;</span>\n</code></pre></div>\n<p>如果所有测试都执行过了，那么你要确保在准确的文件夹和文件名中添加了上述新测试。</p>\n</section>\n</section>\n<section id=\"writing-the-code-for-your-ticket\">\n<h2>为你的工单编写代码<a class=\"heading-anchor\" href=\"#writing-the-code-for-your-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>接下来我们将添加 <code class=\"docutils literal notranslate\"><span class=\"pre\">make_toast()</span></code> 函数</p>\n<p>打开 <code class=\"docutils literal notranslate\"><span class=\"pre\">django/</span></code> 文件夹中的 <code class=\"docutils literal notranslate\"><span class=\"pre\">shortcuts.py</span></code> 文件，在文件末尾追加:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">make_toast</span><span class=\"p\">():</span>\n    <span class=\"k\">return</span> <span class=\"s1\">&#39;toast&#39;</span>\n</code></pre></div>\n<p>现在我们需要保证之前所写的测试会正常通过，以便我们判断所追加的代码是否正确。再来一次，现跳转到Django的 <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> 目录，然后执行:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-7-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py<span class=\"w\"> </span>shortcuts\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-7-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> runtests.py shortcuts\n</code></pre></div></div></div>\n<p>所有项目都需要正常通过测试。如果没有，检查一下你的函数是否书写正确，并且是否写在了正确的文件中。</p>\n</section>\n<section id=\"running-django-s-test-suite-for-the-second-time\">\n<h2>第二次运行 Django 测试套件<a class=\"heading-anchor\" href=\"#running-django-s-test-suite-for-the-second-time\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>如果已经确认补丁以及测试结果都正常，就运行 Django 的测试套件，验证你的修改是否导致 Django 的其它部分引入了新的 bug。 虽然测试用例帮助识别容易被人忽略的错误，但测试通过并不能保证完全没有 bug 存在。</p>\n<p>运行 Django 完整的测试用例，<code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> 进入 Django下的  <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> 目录并运行：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-8-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>./runtests.py\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-8-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> runtests.py \n</code></pre></div></div></div>\n</section>\n<section id=\"writing-documentation\">\n<h2>书写文档<a class=\"heading-anchor\" href=\"#writing-documentation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>这是一项新功能，所以应该为它建立一个说明，打开文件 <code class=\"docutils literal notranslate\"><span class=\"pre\">docs/topics/http/shortcuts.txt</span></code> ，然后在文件末尾追加下记内容:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>``make_toast()``\n================\n\n.. versionadded:: 2.2\n\nReturns ``&#39;toast&#39;``.\n</code></pre></div>\n<p>由于这一新功能将在即将到来的版本中被加入，所以下个版本的发布说明里也加入了相关内容。打开 <code class=\"docutils literal notranslate\"><span class=\"pre\">docs/releases/2.2.txt</span></code> 文件，即发布说明的最新版本文件，在小标题&quot;Minor Features&quot;下面添加一个说明:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>:mod:`django.shortcuts`\n~~~~~~~~~~~~~~~~~~~~~~~\n\n* The new :func:`django.shortcuts.make_toast` function returns ``&#39;toast&#39;``.\n</code></pre></div>\n<p>更多关于编写文档和 <code class=\"docutils literal notranslate\"><span class=\"pre\">versionadded</span></code> 的解释和信息，请参考 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-documentation/\"><span class=\"doc\">编写文档</span></a>。这个页面还介绍了怎么在本地重新生成一份文档，方便你在本地预览文档。</p>\n</section>\n<section id=\"previewing-your-changes\">\n<h2>预览你的修改<a class=\"heading-anchor\" href=\"#previewing-your-changes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>现在是时候完成我们这个分支的所有变更，准备将它们提交了，执行:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-9-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>add<span class=\"w\"> </span>--all\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-9-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> git add --all\n</code></pre></div></div></div>\n<p>然后将你当前版本(包含有你修改的内容)的拷贝和你最初在教程中取出的版本对比:</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-10-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>diff<span class=\"w\"> </span>--cached\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-10-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> git diff --cached\n</code></pre></div></div></div>\n<p>使用方向键上下移动</p>\n<div class=\"code-block\" data-language=\"diff\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Diff</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Diff code\"><code><span class=\"gh\">diff --git a/django/shortcuts.py b/django/shortcuts.py</span>\n<span class=\"gh\">index 7ab1df0e9d..8dde9e28d9 100644</span>\n<span class=\"gd\">--- a/django/shortcuts.py</span>\n<span class=\"gi\">+++ b/django/shortcuts.py</span>\n<span class=\"gu\">@@ -156,3 +156,7 @@ def resolve_url(to, *args, **kwargs):</span>\n\n<span class=\"w\"> </span>    # Finally, fall back and assume it&#39;s a URL\n<span class=\"w\"> </span>    return to\n<span class=\"gi\">+</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+def make_toast():</span>\n<span class=\"gi\">+    return &#39;toast&#39;</span>\n<span class=\"gh\">diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt</span>\n<span class=\"gh\">index 7d85d30c4a..81518187b3 100644</span>\n<span class=\"gd\">--- a/docs/releases/2.2.txt</span>\n<span class=\"gi\">+++ b/docs/releases/2.2.txt</span>\n<span class=\"gu\">@@ -40,6 +40,11 @@ database constraints. Constraints are added to models using the</span>\n<span class=\"w\"> </span>Minor features\n<span class=\"w\"> </span>--------------\n\n<span class=\"gi\">+:mod:`django.shortcuts`</span>\n<span class=\"gi\">+~~~~~~~~~~~~~~~~~~~~~~~</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+* The new :func:`django.shortcuts.make_toast` function returns ``&#39;toast&#39;``.</span>\n<span class=\"gi\">+</span>\n<span class=\"w\"> </span>:mod:`django.contrib.admin`\n<span class=\"w\"> </span>~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n<span class=\"gh\">diff --git a/docs/topics/http/shortcuts.txt b/docs/topics/http/shortcuts.txt</span>\n<span class=\"gh\">index 7b3a3a2c00..711bf6bb6d 100644</span>\n<span class=\"gd\">--- a/docs/topics/http/shortcuts.txt</span>\n<span class=\"gi\">+++ b/docs/topics/http/shortcuts.txt</span>\n<span class=\"gu\">@@ -271,3 +271,12 @@ This example is equivalent to::</span>\n<span class=\"w\"> </span>        my_objects = list(MyModel.objects.filter(published=True))\n<span class=\"w\"> </span>        if not my_objects:\n<span class=\"w\"> </span>            raise Http404(&quot;No MyModel matches the given query.&quot;)\n<span class=\"gi\">+</span>\n<span class=\"gi\">+``make_toast()``</span>\n<span class=\"gi\">+================</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+.. function:: make_toast()</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+.. versionadded:: 2.2</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+Returns ``&#39;toast&#39;``.</span>\n<span class=\"gh\">diff --git a/tests/shortcuts/test_make_toast.py b/tests/shortcuts/test_make_toast.py</span>\nnew file mode 100644\n<span class=\"gh\">index 0000000000..6f4c627b6e</span>\n<span class=\"gd\">--- /dev/null</span>\n<span class=\"gi\">+++ b/tests/shortcuts/test_make_toast.py</span>\n<span class=\"gu\">@@ -0,0 +1,7 @@</span>\n<span class=\"gi\">+from django.shortcuts import make_toast</span>\n<span class=\"gi\">+from django.test import SimpleTestCase</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+class MakeToastTests(SimpleTestCase):</span>\n<span class=\"gi\">+    def test_make_toast(self):</span>\n<span class=\"gi\">+        self.assertEqual(make_toast(), &#39;toast&#39;)</span>\n</code></pre></div>\n<p>当你检查完补丁后，敲击 <code class=\"docutils literal notranslate\"><span class=\"pre\">q</span></code> 键返回到命令行。如果补丁内容看起来没问题，可以提交这些修改了。</p>\n</section>\n<section id=\"committing-the-changes-in-the-patch\">\n<h2>提交补丁中的修改<a class=\"heading-anchor\" href=\"#committing-the-changes-in-the-patch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>为了提交这些修改：</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-11-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>commit\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-11-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> git commit\n</code></pre></div></div></div>\n<p>这会打开文本编辑器以便输入提交信息。参考 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/committing-code/#committing-guidelines\"><span class=\"std std-ref\">commit message guidelines</span></a> 输入类似这样的信息：</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>Fixed #99999 -- Added a shortcut function to make toast.\n</code></pre></div>\n</section>\n<section id=\"pushing-the-commit-and-making-a-pull-request\">\n<h2>推送这次提交并生成一个 pull 请求<a class=\"heading-anchor\" href=\"#pushing-the-commit-and-making-a-pull-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>在提交这次的修改之后，将其发送到你在GitHub上的分支(如果你使用的名称不是&quot;ticket_99999&quot;，用你自己的分支的名称取代它 ):</p>\n<div class=\"console\" data-console><div class=\"console-panel\" data-platform=\"unix\"><p class=\"console-label\" id=\"console-12-unix-label\">Linux / macOS</p><div class=\"code-block\" data-language=\"console\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code><span class=\"gp\">$ </span>git<span class=\"w\"> </span>push<span class=\"w\"> </span>origin<span class=\"w\"> </span>ticket_99999\n</code></pre></div>\n</div><div class=\"console-panel\" data-platform=\"windows\"><p class=\"console-label\" id=\"console-12-windows-label\">Windows</p><div class=\"code-block\" data-language=\"doscon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Windows</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Windows shell\"><code><span class=\"gp\">...\\&gt;</span> git push origin ticket_99999\n</code></pre></div></div></div>\n<p>你可以访问 <a class=\"reference external\" href=\"https://github.com/django/django/\">Django GitHub page</a> 创建一个 pull 请求。 你会在“你最近推送的分支”下看到你的分支。 单击旁边的 &quot;Compare &amp; pull request&quot;。</p>\n<p>本教程中请不要这么做。不过，在接下来显示补丁预览的页面，你可以单击 &quot;Create pull request&quot;。</p>\n</section>\n<section id=\"next-steps\">\n<h2>下一步<a class=\"heading-anchor\" href=\"#next-steps\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>恭喜，你已经学会了如何为 Django 创建 pull request！如需获知更多高级技巧，参考 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/working-with-git/\"><span class=\"doc\">Working with Git and GitHub</span></a>。</p>\n<p>现在你可以活用这些技能帮助改善 Django 的代码库。</p>\n<section id=\"more-information-for-new-contributors\">\n<h3>针对新贡献者的更多注意事项<a class=\"heading-anchor\" href=\"#more-information-for-new-contributors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>在你开始为 Django 编写补丁时，这里有些信息，你应该看一看：</p>\n<ul class=\"simple\">\n<li><p>确保你阅读了 Django 的参考文档 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">创建工单和提交补丁</span></a>。它涵盖了Trac 规则，如何创建自己的工单，补丁期望的代码风格和其他一些重要信息。</p></li>\n<li><p>初次提交补丁应额外阅读 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/new-contributors/\"><span class=\"doc\">首次贡献者文档</span></a>。这里有很多对新手贡献者的建议。</p></li>\n<li><p>接下来，如果你渴望更多关于为 Django 做贡献的信息，可以阅读余下的文档 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/\"><span class=\"doc\">为 Django 文档上作出贡献</span></a>。它包含了大量的有用信息，这里可以解决你可能遇到的所有问题。</p></li>\n</ul>\n</section>\n<section id=\"finding-your-first-real-ticket\">\n<h3>寻找你的第一个真正意义上的工单<a class=\"heading-anchor\" href=\"#finding-your-first-real-ticket\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>一旦你看过了之前那些信息，你便已经具备了走出困境，编写修复自己找到的工单的补丁的能力。对于那些有着“容易获得”标准的工单要尤其注意。这些工单实际上常常很简单而且对于第一次撰写补丁的人很有帮助。一旦你熟悉了给 Django 写补丁，你就可以进一步为更难且更复杂的工单写补丁。</p>\n<p>如果你只是想要简单的了解（没人会因此责备你！），那么你可以试着看看 <a href=\"#id11\"><span class=\"problematic\" id=\"id17\">`easy tickets that need patches`__</span></a> 和 <a href=\"#id11\"><span class=\"problematic\" id=\"id18\">`easy tickets that have patches which need improvement`__</span></a>。如果你比较擅长写测试，那么你也可以看看这个 <a href=\"#id11\"><span class=\"problematic\" id=\"id19\">`easy tickets that need tests`__</span></a>。一定要记得遵循在 Django 的文档声明标签和递交补丁中提到的关于声明标签的指导规则 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">声明标签和提交补丁</span></a>.</p>\n</section>\n<section id=\"what-s-next-after-creating-a-pull-request\">\n<h3>创建完 pull request，下一步做什么呢？<a class=\"heading-anchor\" href=\"#what-s-next-after-creating-a-pull-request\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>工单有了补丁后，需要他人来复审。提交 pull 请求后，为工单打上如“有补丁”，“无需测试”之类的标签，如此他人便可查找到该工单以便复审。从头开始编写补丁固然是贡献的一种方式，但复审已有补丁同样能帮助 Django。 查看 <a class=\"reference internal\" href=\"/zh-hans/3.0/internals/contributing/triaging-tickets/\"><span class=\"doc\">Triaging tickets</span></a> 了解更多。</p>\n</section>\n</section>","rootId":"writing-your-first-patch-for-django","toc":[{"title":"介绍","anchor":"introduction","children":[{"title":"这个教程适合谁？","anchor":"who-s-this-tutorial-for","children":[]},{"title":"这个指南涵盖哪些内容？","anchor":"what-does-this-tutorial-cover","children":[]}]},{"title":"代码规范","anchor":"code-of-conduct","children":[]},{"title":"安装Git","anchor":"installing-git","children":[]},{"title":"获得一个 Django 开发版本的副本","anchor":"getting-a-copy-of-django-s-development-version","children":[{"title":"使用 Django 本地副本创建项目","anchor":"creating-projects-with-a-local-copy-of-django","children":[]}]},{"title":"首先运行 Django 的测试套件","anchor":"running-django-s-test-suite-for-the-first-time","children":[]},{"title":"尝试搞定一项新功能","anchor":"working-on-a-feature","children":[]},{"title":"为你的补丁创建一个分支","anchor":"creating-a-branch-for-your-patch","children":[]},{"title":"为你的工单写一些测试用例","anchor":"writing-some-tests-for-your-ticket","children":[{"title":"为工单 #99999 写测试","anchor":"writing-a-test-for-ticket-99999","children":[]},{"title":"运行你的新测试","anchor":"running-your-new-test","children":[]}]},{"title":"为你的工单编写代码","anchor":"writing-the-code-for-your-ticket","children":[]},{"title":"第二次运行 Django 测试套件","anchor":"running-django-s-test-suite-for-the-second-time","children":[]},{"title":"书写文档","anchor":"writing-documentation","children":[]},{"title":"预览你的修改","anchor":"previewing-your-changes","children":[]},{"title":"提交补丁中的修改","anchor":"committing-the-changes-in-the-patch","children":[]},{"title":"推送这次提交并生成一个 pull 请求","anchor":"pushing-the-commit-and-making-a-pull-request","children":[]},{"title":"下一步","anchor":"next-steps","children":[{"title":"针对新贡献者的更多注意事项","anchor":"more-information-for-new-contributors","children":[]},{"title":"寻找你的第一个真正意义上的工单","anchor":"finding-your-first-real-ticket","children":[]},{"title":"创建完 pull request，下一步做什么呢？","anchor":"what-s-next-after-creating-a-pull-request","children":[]}]}],"breadcrumbs":[{"docname":"intro/index","title":"开始","url":"/zh-hans/3.0/intro/"}],"prev":{"docname":"intro/whatsnext","title":"下一步看什么","url":"/zh-hans/3.0/intro/whatsnext/"},"next":{"docname":"topics/index","title":"使用 Django","url":"/zh-hans/3.0/topics/"},"formats":{"html":"/zh-hans/3.0/intro/contributing/","markdown":"/zh-hans/3.0/intro/contributing.md","json":"/zh-hans/3.0/intro/contributing.json"},"source":"https://github.com/django/django/blob/stable/3.0.x/docs/intro/contributing.txt","official":"https://docs.djangoproject.com/zh-hans/3.0/intro/contributing/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}