{"title":"Writing your first patch for Django","version":"4.2","locale":"en","docname":"intro/contributing","url":"/en/4.2/intro/contributing/","canonical":"https://djangodocs.dev/en/4.2/intro/contributing/","summary":"Introduction Link to this heading # Interested in giving back to the community a little? Maybe you’ve found a bug in Django that you’d like to see fixed, or maybe…","html":"<h1>Writing your first patch for 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>Introduction<a class=\"heading-anchor\" href=\"#introduction\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Interested in giving back to the community a little? Maybe you’ve found a bug\nin Django that you’d like to see fixed, or maybe there’s a small feature you\nwant added.</p>\n<p>Contributing back to Django itself is the best way to see your own concerns\naddressed. This may seem daunting at first, but it’s a well-traveled path with\ndocumentation, tooling, and a community to support you. We’ll walk you through\nthe entire process, so you can learn by example.</p>\n<section id=\"who-s-this-tutorial-for\">\n<h3>Who’s this tutorial for?<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>If you are looking for a reference on the details of making code\ncontributions, see the <a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/\"><span class=\"doc\">Writing code</span></a>\ndocumentation.</p>\n</aside>\n<p>For this tutorial, we expect that you have at least a basic understanding of\nhow Django works. This means you should be comfortable going through the\nexisting tutorials on <a class=\"reference internal\" href=\"/en/4.2/intro/tutorial01/\"><span class=\"doc\">writing your first Django app</span></a>.\nIn addition, you should have a good understanding of Python itself. But if you\ndon’t, <a class=\"reference external\" href=\"https://diveinto.org/python3/table-of-contents.html\">Dive Into Python</a> is a fantastic (and free) online book for\nbeginning Python programmers.</p>\n<p>Those of you who are unfamiliar with version control systems and Trac will find\nthat this tutorial and its links include just enough information to get started.\nHowever, you’ll probably want to read some more about these different tools if\nyou plan on contributing to Django regularly.</p>\n<p>For the most part though, this tutorial tries to explain as much as possible,\nso that it can be of use to the widest audience.</p>\n<aside class=\"admonition-where-to-get-help admonition\">\n<p class=\"admonition-title\">Where to get help:</p>\n<p>If you’re having trouble going through this tutorial, please post a message\non the <a class=\"reference external\" href=\"https://forum.djangoproject.com/\">Django Forum</a>, <a class=\"reference internal\" href=\"/en/4.2/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a>, or drop by\n<a class=\"reference external\" href=\"https://web.libera.chat/#django-dev\">#django-dev on irc.libera.chat</a> to chat with other Django users who\nmight be able to help.</p>\n</aside>\n</section>\n<section id=\"what-does-this-tutorial-cover\">\n<h3>What does this tutorial cover?<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>We’ll be walking you through contributing a patch to Django for the first time.\nBy the end of this tutorial, you should have a basic understanding of both the\ntools and the processes involved. Specifically, we’ll be covering the following:</p>\n<ul class=\"simple\">\n<li><p>Installing Git.</p></li>\n<li><p>Downloading a copy of Django’s development version.</p></li>\n<li><p>Running Django’s test suite.</p></li>\n<li><p>Writing a test for your patch.</p></li>\n<li><p>Writing the code for your patch.</p></li>\n<li><p>Testing your patch.</p></li>\n<li><p>Submitting a pull request.</p></li>\n<li><p>Where to look for more information.</p></li>\n</ul>\n<p>Once you’re done with the tutorial, you can look through the rest of\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/\"><span class=\"doc\">Django’s documentation on contributing</span></a>.\nIt contains lots of great information and is a must read for anyone who’d like\nto become a regular contributor to Django. If you’ve got questions, it’s\nprobably got the answers.</p>\n<aside class=\"admonition-python-3-required admonition\">\n<p class=\"admonition-title\">Python 3 required!</p>\n<p>The current version of Django doesn’t support Python 2.7. Get Python 3 at\n<a class=\"reference external\" href=\"https://www.python.org/downloads/\">Python’s download page</a> or with your\noperating system’s package manager.</p>\n</aside>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">For Windows users</p>\n<p>See <a class=\"reference internal\" href=\"/en/4.2/howto/windows/#install-python-windows\"><span class=\"std std-ref\">Install Python</span></a> on Windows docs for additional guidance.</p>\n</aside>\n</section>\n</section>\n<section id=\"code-of-conduct\">\n<h2>Code of Conduct<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>As a contributor, you can help us keep the Django community open and inclusive.\nPlease read and follow our <a class=\"reference external\" href=\"https://www.djangoproject.com/conduct/\">Code of Conduct</a>.</p>\n</section>\n<section id=\"installing-git\">\n<h2>Installing 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>For this tutorial, you’ll need Git installed to download the current\ndevelopment version of Django and to generate patch files for the changes you\nmake.</p>\n<p>To check whether or not you have Git installed, enter <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span></code> into the command\nline. If you get messages saying that this command could not be found, you’ll\nhave to download and install it, see <a class=\"reference external\" href=\"https://git-scm.com/download\">Git’s download page</a>.</p>\n<p>If you’re not that familiar with Git, you can always find out more about its\ncommands (once it’s installed) by typing <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span> <span class=\"pre\">help</span></code> into the command line.</p>\n</section>\n<section id=\"getting-a-copy-of-django-s-development-version\">\n<h2>Getting a copy of Django’s development version<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>The first step to contributing to Django is to get a copy of the source code.\nFirst, <a class=\"reference external\" href=\"https://github.com/django/django/fork\">fork Django on GitHub</a>. Then,\nfrom the command line, use the <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> command to navigate to the directory\nwhere you’ll want your local copy of Django to live.</p>\n<p>Download the Django source code repository using the following command:</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\">Low bandwidth connection?</p>\n<p>You can add the <code class=\"docutils literal notranslate\"><span class=\"pre\">--depth</span> <span class=\"pre\">1</span></code> argument to <code class=\"docutils literal notranslate\"><span class=\"pre\">git</span> <span class=\"pre\">clone</span></code> to skip downloading\nall of Django’s commit history, which reduces data transfer from  ~250 MB\nto ~70 MB.</p>\n</aside>\n<p>Now that you have a local copy of Django, you can install it just like you would\ninstall any package using <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code>. The most convenient way to do so is by using\na <em>virtual environment</em>, which is a feature built into Python that allows you\nto keep a separate directory of installed packages for each of your projects so\nthat they don’t interfere with each other.</p>\n<p>It’s a good idea to keep all your virtual environments in one place, for\nexample in <code class=\"docutils literal notranslate\"><span class=\"pre\">.virtualenvs/</span></code> in your home directory.</p>\n<p>Create a new virtual environment by running:</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>The path is where the new environment will be saved on your computer.</p>\n<p>The final step in setting up your virtual environment is to activate it:</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>If the <code class=\"docutils literal notranslate\"><span class=\"pre\">source</span></code> command is not available, you can try using a dot instead:</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>You have to activate the virtual environment whenever you open a new\nterminal window.</p>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">For Windows users</p>\n<p>To activate your virtual environment on Windows, run:</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>The name of the currently activated virtual environment is displayed on the\ncommand line to help you keep track of which one you are using. Anything you\ninstall through <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code> while this name is displayed will be installed in that\nvirtual environment, isolated from other environments and system-wide packages.</p>\n<p id=\"intro-contributing-install-local-copy\">Go ahead and install the previously cloned copy of 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>The installed version of Django is now pointing at your local copy by installing\nin editable mode. You will immediately see any changes you make to it, which is\nof great help when writing your first patch.</p>\n<section id=\"creating-projects-with-a-local-copy-of-django\">\n<h3>Creating projects with a local copy of 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>It may be helpful to test your local changes with a Django project. First you\nhave to create a new virtual environment, <a class=\"reference internal\" href=\"#intro-contributing-install-local-copy\"><span class=\"std std-ref\">install the previously cloned\nlocal copy of Django in editable mode</span></a>,\nand create a new Django project outside of your local copy of Django. You will\nimmediately see any changes you make to Django in your new project, which is\nof great help when writing your first patch, especially if testing any changes\nto the UI.</p>\n<p>You can follow the <a class=\"reference internal\" href=\"/en/4.2/intro/tutorial01/\"><span class=\"doc\">tutorial</span></a> for help in creating a\nDjango project.</p>\n</section>\n</section>\n<section id=\"running-django-s-test-suite-for-the-first-time\">\n<h2>Running Django’s test suite for the first time<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>When contributing to Django it’s very important that your code changes don’t\nintroduce bugs into other areas of Django. One way to check that Django still\nworks after you make your changes is by running Django’s test suite. If all\nthe tests still pass, then you can be reasonably sure that your changes\nwork and haven’t broken other parts of Django. If you’ve never run Django’s test\nsuite before, it’s a good idea to run it once beforehand to get familiar with\nits output.</p>\n<p>Before running the test suite, enter the Django <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> directory using the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span> <span class=\"pre\">tests</span></code> command, and install test dependencies by running:</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>If you encounter an error during the installation, your system might be missing\na dependency for one or more of the Python packages. Consult the failing\npackage’s documentation or search the web with the error message that you\nencounter.</p>\n<p>Now we are ready to run the test suite. If you’re using GNU/Linux, macOS, or\nsome other flavor of Unix, run:</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>Now sit back and relax. Django’s entire test suite has thousands of tests, and\nit takes at least a few minutes to run, depending on the speed of your\ncomputer.</p>\n<p>While Django’s test suite is running, you’ll see a stream of characters\nrepresenting the status of each test as it completes. <code class=\"docutils literal notranslate\"><span class=\"pre\">E</span></code> indicates that an\nerror was raised during a test, and <code class=\"docutils literal notranslate\"><span class=\"pre\">F</span></code> indicates that a test’s assertions\nfailed. Both of these are considered to be test failures. Meanwhile, <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> and\n<code class=\"docutils literal notranslate\"><span class=\"pre\">s</span></code> indicated expected failures and skipped tests, respectively. Dots indicate\npassing tests.</p>\n<p>Skipped tests are typically due to missing external libraries required to run\nthe test; see <a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/unit-tests/#running-unit-tests-dependencies\"><span class=\"std std-ref\">Running all the tests</span></a> for a list of dependencies\nand be sure to install any for tests related to the changes you are making (we\nwon’t need any for this tutorial). Some tests are specific to a particular\ndatabase backend and will be skipped if not testing with that backend. SQLite\nis the database backend for the default settings. To run the tests using a\ndifferent backend, see <a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">Using another settings module</span></a>.</p>\n<p>Once the tests complete, you should be greeted with a message informing you\nwhether the test suite passed or failed. Since you haven’t yet made any changes\nto Django’s code, the entire test suite <strong>should</strong> pass. If you get failures or\nerrors make sure you’ve followed all of the previous steps properly. See\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/unit-tests/#running-unit-tests\"><span class=\"std std-ref\">Running the unit tests</span></a> for more information.</p>\n<p>Note that the latest Django “main” branch may not always be stable. When\ndeveloping against “main”, you can check <a class=\"reference external\" href=\"https://djangoci.com\">Django’s continuous integration\nbuilds</a> to determine if the failures are specific to your machine or if they\nare also present in Django’s official builds. If you click to view a particular\nbuild, you can view the “Configuration Matrix” which shows failures broken down\nby Python version and database backend.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>For this tutorial and the ticket we’re working on, testing against SQLite\nis sufficient, however, it’s possible (and sometimes necessary) to\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">run the tests using a different database</span></a>. When making UI changes, you will need to\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/unit-tests/#running-selenium-tests\"><span class=\"std std-ref\">run the Selenium tests</span></a>.</p>\n</aside>\n</section>\n<section id=\"working-on-a-feature\">\n<h2>Working on a feature<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>For this tutorial, we’ll work on a “fake ticket” as a case study. Here are the\nimaginary details:</p>\n<aside class=\"admonition-ticket-99999-allow-making-toast admonition\">\n<p class=\"admonition-title\">Ticket #99999 – Allow making toast</p>\n<p>Django should provide a function <code class=\"docutils literal notranslate\"><span class=\"pre\">django.shortcuts.make_toast()</span></code> that\nreturns <code class=\"docutils literal notranslate\"><span class=\"pre\">'toast'</span></code>.</p>\n</aside>\n<p>We’ll now implement this feature and associated tests.</p>\n</section>\n<section id=\"creating-a-branch-for-your-patch\">\n<h2>Creating a branch for your patch<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>Before making any changes, create a new branch for the ticket:</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>You can choose any name that you want for the branch, “ticket_99999” is an\nexample. All changes made in this branch will be specific to the ticket and\nwon’t affect the main copy of the code that we cloned earlier.</p>\n</section>\n<section id=\"writing-some-tests-for-your-ticket\">\n<h2>Writing some tests for your ticket<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>In most cases, for a patch to be accepted into Django it has to include tests.\nFor bug fix patches, this means writing a regression test to ensure that the\nbug is never reintroduced into Django later on. A regression test should be\nwritten in such a way that it will fail while the bug still exists and pass\nonce the bug has been fixed. For patches containing new features, you’ll need\nto include tests which ensure that the new features are working correctly.\nThey too should fail when the new feature is not present, and then pass once it\nhas been implemented.</p>\n<p>A good way to do this is to write your new tests first, before making any\nchanges to the code. This style of development is called\n<a class=\"reference external\" href=\"https://en.wikipedia.org/wiki/Test-driven_development\">test-driven development</a> and can be applied to both entire projects and\nsingle patches. After writing your tests, you then run them to make sure that\nthey do indeed fail (since you haven’t fixed that bug or added that feature\nyet). If your new tests don’t fail, you’ll need to fix them so that they do.\nAfter all, a regression test that passes regardless of whether a bug is present\nis not very helpful at preventing that bug from reoccurring down the road.</p>\n<p>Now for our hands-on example.</p>\n<section id=\"writing-a-test-for-ticket-99999\">\n<h3>Writing a test for ticket #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>In order to resolve this ticket, we’ll add a <code class=\"docutils literal notranslate\"><span class=\"pre\">make_toast()</span></code> function to the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">django.shortcuts</span></code> module. First we are going to write a test that tries to\nuse the function and check that its output looks correct.</p>\n<p>Navigate to Django’s <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/shortcuts/</span></code> folder and create a new file\n<code class=\"docutils literal notranslate\"><span class=\"pre\">test_make_toast.py</span></code>. Add the following 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=\"s2\">&quot;toast&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>This test checks that the <code class=\"docutils literal notranslate\"><span class=\"pre\">make_toast()</span></code> returns <code class=\"docutils literal notranslate\"><span class=\"pre\">'toast'</span></code>.</p>\n<aside class=\"admonition-but-this-testing-thing-looks-kinda-hard admonition\">\n<p class=\"admonition-title\">But this testing thing looks kinda hard…</p>\n<p>If you’ve never had to deal with tests before, they can look a little hard\nto write at first glance. Fortunately, testing is a <em>very</em> big subject in\ncomputer programming, so there’s lots of information out there:</p>\n<ul class=\"simple\">\n<li><p>A good first look at writing tests for Django can be found in the\ndocumentation on <a class=\"reference internal\" href=\"/en/4.2/topics/testing/overview/\"><span class=\"doc\">Writing and running tests</span></a>.</p></li>\n<li><p>Dive Into Python (a free online book for beginning Python developers)\nincludes a great <a class=\"reference external\" href=\"https://diveinto.org/python3/unit-testing.html\">introduction to Unit Testing</a>.</p></li>\n<li><p>After reading those, if you want something a little meatier to sink\nyour teeth into, there’s always the 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> documentation.</p></li>\n</ul>\n</aside>\n</section>\n<section id=\"running-your-new-test\">\n<h3>Running your new test<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>Since we haven’t made any modifications to <code class=\"docutils literal notranslate\"><span class=\"pre\">django.shortcuts</span></code> yet, our test\nshould fail. Let’s run all the tests in the <code class=\"docutils literal notranslate\"><span class=\"pre\">shortcuts</span></code> folder to make sure\nthat’s really what happens. <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> to the Django <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> directory and run:</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>If the tests ran correctly, you should see one failure corresponding to the test\nmethod we added, with this error:</p>\n<div class=\"code-block\" data-language=\"pytb\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Pytb</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=\"Pytb code\"><code><span class=\"x\">ImportError: cannot import name &#39;make_toast&#39; from &#39;django.shortcuts&#39;</span>\n</code></pre></div>\n<p>If all of the tests passed, then you’ll want to make sure that you added the\nnew test shown above to the appropriate folder and file name.</p>\n</section>\n</section>\n<section id=\"writing-the-code-for-your-ticket\">\n<h2>Writing the code for your ticket<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>Next we’ll be adding the <code class=\"docutils literal notranslate\"><span class=\"pre\">make_toast()</span></code> function.</p>\n<p>Navigate to the <code class=\"docutils literal notranslate\"><span class=\"pre\">django/</span></code> folder and open the <code class=\"docutils literal notranslate\"><span class=\"pre\">shortcuts.py</span></code> file. At the\nbottom, add:</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=\"s2\">&quot;toast&quot;</span>\n</code></pre></div>\n<p>Now we need to make sure that the test we wrote earlier passes, so we can see\nwhether the code we added is working correctly. Again, navigate to the Django\n<code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> directory and run:</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>Everything should pass. If it doesn’t, make sure you correctly added the\nfunction to the correct file.</p>\n</section>\n<section id=\"running-django-s-test-suite-for-the-second-time\">\n<h2>Running Django’s test suite for the second time<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>Once you’ve verified that your patch and your test are working correctly, it’s\na good idea to run the entire Django test suite to verify that your change\nhasn’t introduced any bugs into other areas of Django. While successfully\npassing the entire test suite doesn’t guarantee your code is bug free, it does\nhelp identify many bugs and regressions that might otherwise go unnoticed.</p>\n<p>To run the entire Django test suite, <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> into the Django <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code>\ndirectory and run:</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>Writing Documentation<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>This is a new feature, so it should be documented. Open the file\n<code class=\"docutils literal notranslate\"><span class=\"pre\">docs/topics/http/shortcuts.txt</span></code> and add the following at the end of the\nfile:</p>\n<div class=\"code-block\" data-language=\"rst\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Rst</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=\"Rst code\"><code><span class=\"gh\">``make_toast()``</span>\n<span class=\"gh\">================</span>\n\n<span class=\"p\">..</span> <span class=\"ow\">function</span><span class=\"p\">::</span> make_toast()\n\n<span class=\"p\">..</span> <span class=\"ow\">versionadded</span><span class=\"p\">::</span> 2.2\n\nReturns <span class=\"s\">``&#39;toast&#39;``</span>.\n</code></pre></div>\n<p>Since this new feature will be in an upcoming release it is also added to the\nrelease notes for the next version of Django. Open the release notes for the\nlatest version in <code class=\"docutils literal notranslate\"><span class=\"pre\">docs/releases/</span></code>, which at time of writing is <code class=\"docutils literal notranslate\"><span class=\"pre\">2.2.txt</span></code>.\nAdd a note under the “Minor Features” header:</p>\n<div class=\"code-block\" data-language=\"rst\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Rst</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=\"Rst code\"><code><span class=\"gh\">:mod:`django.shortcuts`</span>\n<span class=\"gh\">~~~~~~~~~~~~~~~~~~~~~~~</span>\n\n<span class=\"m\">*</span> The new <span class=\"na\">:func:</span><span class=\"nv\">`django.shortcuts.make_toast`</span> function returns <span class=\"s\">``&#39;toast&#39;``</span>.\n</code></pre></div>\n<p>For more information on writing documentation, including an explanation of what\nthe <code class=\"docutils literal notranslate\"><span class=\"pre\">versionadded</span></code> bit is all about, see\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-documentation/\"><span class=\"doc\">Writing documentation</span></a>. That page also includes\nan explanation of how to build a copy of the documentation locally, so you can\npreview the HTML that will be generated.</p>\n</section>\n<section id=\"previewing-your-changes\">\n<h2>Previewing your changes<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>Now it’s time to go through all the changes made in our patch. To stage all the\nchanges ready for commit, run:</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>Then display the differences between your current copy of Django (with your\nchanges) and the revision that you initially checked out earlier in the\ntutorial with:</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>Use the arrow keys to move up and down.</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>When you’re done previewing the patch, hit the <code class=\"docutils literal notranslate\"><span class=\"pre\">q</span></code> key to return to the\ncommand line. If the patch’s content looked okay, it’s time to commit the\nchanges.</p>\n</section>\n<section id=\"committing-the-changes-in-the-patch\">\n<h2>Committing the changes in the patch<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>To commit the changes:</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>This opens up a text editor to type the commit message. Follow the <a class=\"reference internal\" href=\"/en/4.2/internals/contributing/committing-code/#committing-guidelines\"><span class=\"std std-ref\">commit\nmessage guidelines</span></a> and write a message like:</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>Pushing the commit and making a pull request<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>After committing the patch, send it to your fork on GitHub (substitute\n“ticket_99999” with the name of your branch if it’s different):</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>You can create a pull request by visiting the <a class=\"reference external\" href=\"https://github.com/django/django/\">Django GitHub page</a>. You’ll see your branch under “Your\nrecently pushed branches”. Click “Compare &amp; pull request” next to it.</p>\n<p>Please don’t do it for this tutorial, but on the next page that displays a\npreview of the patch, you would click “Create pull request”.</p>\n</section>\n<section id=\"next-steps\">\n<h2>Next steps<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>Congratulations, you’ve learned how to make a pull request to Django! Details\nof more advanced techniques you may need are in\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/working-with-git/\"><span class=\"doc\">Working with Git and GitHub</span></a>.</p>\n<p>Now you can put those skills to good use by helping to improve Django’s\ncodebase.</p>\n<section id=\"more-information-for-new-contributors\">\n<h3>More information for new contributors<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>Before you get too into writing patches for Django, there’s a little more\ninformation on contributing that you should probably take a look at:</p>\n<ul class=\"simple\">\n<li><p>You should make sure to read Django’s documentation on\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">claiming tickets and submitting patches</span></a>.\nIt covers Trac etiquette, how to claim tickets for yourself, expected\ncoding style for patches, and many other important details.</p></li>\n<li><p>First time contributors should also read Django’s <a class=\"reference internal\" href=\"/en/4.2/internals/contributing/new-contributors/\"><span class=\"doc\">documentation\nfor first time contributors</span></a>.\nIt has lots of good advice for those of us who are new to helping out\nwith Django.</p></li>\n<li><p>After those, if you’re still hungry for more information about\ncontributing, you can always browse through the rest of\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/\"><span class=\"doc\">Django’s documentation on contributing</span></a>.\nIt contains a ton of useful information and should be your first source\nfor answering any questions you might have.</p></li>\n</ul>\n</section>\n<section id=\"finding-your-first-real-ticket\">\n<h3>Finding your first real ticket<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>Once you’ve looked through some of that information, you’ll be ready to go out\nand find a ticket of your own to write a patch for. Pay special attention to\ntickets with the “easy pickings” criterion. These tickets are often much\nsimpler in nature and are great for first time contributors. Once you’re\nfamiliar with contributing to Django, you can move on to writing patches for\nmore difficult and complicated tickets.</p>\n<p>If you just want to get started already (and nobody would blame you!), try\ntaking a look at the list of <a class=\"reference external\" href=\"https://code.djangoproject.com/query?status=new&amp;status=reopened&amp;has_patch=0&amp;easy=1&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=milestone&amp;order=priority\">easy tickets that need patches</a> and the\n<a class=\"reference external\" href=\"https://code.djangoproject.com/query?status=new&amp;status=reopened&amp;needs_better_patch=1&amp;easy=1&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=milestone&amp;order=priority\">easy tickets that have patches which need improvement</a>. If you’re familiar\nwith writing tests, you can also look at the list of\n<a class=\"reference external\" href=\"https://code.djangoproject.com/query?status=new&amp;status=reopened&amp;needs_tests=1&amp;easy=1&amp;col=id&amp;col=summary&amp;col=status&amp;col=owner&amp;col=type&amp;col=milestone&amp;order=priority\">easy tickets that need tests</a>. Remember to follow the guidelines about\nclaiming tickets that were mentioned in the link to Django’s documentation on\n<a class=\"reference internal\" href=\"/en/4.2/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">claiming tickets and submitting patches</span></a>.</p>\n</section>\n<section id=\"what-s-next-after-creating-a-pull-request\">\n<h3>What’s next after creating a 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>After a ticket has a patch, it needs to be reviewed by a second set of eyes.\nAfter submitting a pull request, update the ticket metadata by setting the\nflags on the ticket to say “has patch”, “doesn’t need tests”, etc, so others\ncan find it for review. Contributing doesn’t necessarily always mean writing a\npatch from scratch. Reviewing existing patches is also a very helpful\ncontribution. See <a class=\"reference internal\" href=\"/en/4.2/internals/contributing/triaging-tickets/\"><span class=\"doc\">Triaging tickets</span></a> for details.</p>\n</section>\n</section>","rootId":"writing-your-first-patch-for-django","toc":[{"title":"Introduction","anchor":"introduction","children":[{"title":"Who’s this tutorial for?","anchor":"who-s-this-tutorial-for","children":[]},{"title":"What does this tutorial cover?","anchor":"what-does-this-tutorial-cover","children":[]}]},{"title":"Code of Conduct","anchor":"code-of-conduct","children":[]},{"title":"Installing Git","anchor":"installing-git","children":[]},{"title":"Getting a copy of Django’s development version","anchor":"getting-a-copy-of-django-s-development-version","children":[{"title":"Creating projects with a local copy of Django","anchor":"creating-projects-with-a-local-copy-of-django","children":[]}]},{"title":"Running Django’s test suite for the first time","anchor":"running-django-s-test-suite-for-the-first-time","children":[]},{"title":"Working on a feature","anchor":"working-on-a-feature","children":[]},{"title":"Creating a branch for your patch","anchor":"creating-a-branch-for-your-patch","children":[]},{"title":"Writing some tests for your ticket","anchor":"writing-some-tests-for-your-ticket","children":[{"title":"Writing a test for ticket #99999","anchor":"writing-a-test-for-ticket-99999","children":[]},{"title":"Running your new test","anchor":"running-your-new-test","children":[]}]},{"title":"Writing the code for your ticket","anchor":"writing-the-code-for-your-ticket","children":[]},{"title":"Running Django’s test suite for the second time","anchor":"running-django-s-test-suite-for-the-second-time","children":[]},{"title":"Writing Documentation","anchor":"writing-documentation","children":[]},{"title":"Previewing your changes","anchor":"previewing-your-changes","children":[]},{"title":"Committing the changes in the patch","anchor":"committing-the-changes-in-the-patch","children":[]},{"title":"Pushing the commit and making a pull request","anchor":"pushing-the-commit-and-making-a-pull-request","children":[]},{"title":"Next steps","anchor":"next-steps","children":[{"title":"More information for new contributors","anchor":"more-information-for-new-contributors","children":[]},{"title":"Finding your first real ticket","anchor":"finding-your-first-real-ticket","children":[]},{"title":"What’s next after creating a pull request?","anchor":"what-s-next-after-creating-a-pull-request","children":[]}]}],"breadcrumbs":[{"docname":"intro/index","title":"Getting started","url":"/en/4.2/intro/"}],"prev":{"docname":"intro/whatsnext","title":"What to read next","url":"/en/4.2/intro/whatsnext/"},"next":{"docname":"topics/index","title":"Using Django","url":"/en/4.2/topics/"},"formats":{"html":"/en/4.2/intro/contributing/","markdown":"/en/4.2/intro/contributing.md","json":"/en/4.2/intro/contributing.json"},"source":"https://github.com/django/django/blob/stable/4.2.x/docs/intro/contributing.txt","official":"https://docs.djangoproject.com/en/4.2/intro/contributing/","inVersions":["dev","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","1.11","1.10","1.9","1.8"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}