{"title":"Writing your first patch for Django","version":"1.11","locale":"en","docname":"intro/contributing","url":"/en/1.11/intro/contributing/","canonical":"https://djangodocs.dev/en/1.11/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 really pretty simple.\nWe’ll walk you through the 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 how to submit patches, see the\n<a class=\"reference internal\" href=\"/en/1.11/internals/contributing/writing-code/submitting-patches/\"><span class=\"doc\">Submitting patches</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/1.11/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=\"http://www.diveintopython3.net/\">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\nto <a class=\"reference internal\" href=\"/en/1.11/internals/mailing-lists/#django-developers-mailing-list\"><span class=\"std std-ref\">django-developers</span></a> or drop by <a class=\"reference external\" href=\"irc://irc.freenode.net/django-dev\">#django-dev on irc.freenode.net</a> to\nchat with other Django users who might 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>How to download a development copy of Django.</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/1.11/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>This tutorial assumes you are using Python 3. Get the latest version 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>When installing Python on Windows, make sure you check the option “Add\npython.exe to Path”, so that it is always available on the command line.</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<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">For Windows users</p>\n<p>When installing Git on Windows, it is recommended that you pick the\n“Git Bash” option so that Git runs in its own shell. This tutorial assumes\nthat’s how you have installed it.</p>\n</aside>\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=\"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>git@github.com:YourGitHubName/django.git\n</code></pre></div>\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> (or virtualenv) which is a feature built into Python\nthat allows you to keep a separate directory of installed packages for each of\nyour projects so that they don’t interfere with each other.</p>\n<p>It’s a good idea to keep all your virtualenvs in one place, for example in\n<code class=\"docutils literal notranslate\"><span class=\"pre\">.virtualenvs/</span></code> in your home directory. Create it if it doesn’t exist yet:</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>mkdir<span class=\"w\"> </span>~/.virtualenvs\n</code></pre></div>\n<p>Now create a new virtualenv by running:</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>python3<span class=\"w\"> </span>-m<span class=\"w\"> </span>venv<span class=\"w\"> </span>~/.virtualenvs/djangodev\n</code></pre></div>\n<p>The path is where the new environment will be saved on your computer.</p>\n<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">For Windows users</p>\n<p>Using the built-in <code class=\"docutils literal notranslate\"><span class=\"pre\">venv</span></code> module will not work if you are also using the\nGit Bash shell on Windows, since activation scripts are only created for the\nsystem shell (<code class=\"docutils literal notranslate\"><span class=\"pre\">.bat</span></code>) and PowerShell (<code class=\"docutils literal notranslate\"><span class=\"pre\">.ps1</span></code>). Use the <code class=\"docutils literal notranslate\"><span class=\"pre\">virtualenv</span></code>\npackage instead:</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</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=\"None code\"><code>$ pip install virtualenv\n$ virtualenv ~/.virtualenvs/djangodev\n</code></pre></div>\n</aside>\n<aside class=\"admonition-for-ubuntu-users admonition\">\n<p class=\"admonition-title\">For Ubuntu users</p>\n<p>On some versions of Ubuntu the above command might fail. Use the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">virtualenv</span></code> package instead, first making sure you have <code class=\"docutils literal notranslate\"><span class=\"pre\">pip3</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>sudo<span class=\"w\"> </span>apt-get<span class=\"w\"> </span>install<span class=\"w\"> </span>python3-pip\n<span class=\"gp\">$ </span><span class=\"c1\"># Prefix the next command with sudo if it gives a permission denied error</span>\n<span class=\"gp\">$ </span>pip3<span class=\"w\"> </span>install<span class=\"w\"> </span>virtualenv\n<span class=\"gp\">$ </span>virtualenv<span class=\"w\"> </span>--python<span class=\"o\">=</span><span class=\"sb\">`</span>which<span class=\"w\"> </span>python3<span class=\"sb\">`</span><span class=\"w\"> </span>~/.virtualenvs/djangodev\n</code></pre></div>\n</aside>\n<p>The final step in setting up your virtualenv 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<aside class=\"admonition-for-windows-users admonition\">\n<p class=\"admonition-title\">For Windows users</p>\n<p>To activate your virtualenv on Windows, run:</p>\n<div class=\"code-block\" data-language=\"none\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">None</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=\"None code\"><code>$ source ~/virtualenvs/djangodev/Scripts/activate\n</code></pre></div>\n</aside>\n<p>You have to activate the virtualenv whenever you open a new terminal window.\n<a class=\"reference external\" href=\"https://virtualenvwrapper.readthedocs.io/en/latest/\">virtualenvwrapper</a> is a useful tool for making this more convenient.</p>\n<p>Anything you install through <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code> from now on will be installed in your new\nvirtualenv, isolated from other environments and system-wide packages. Also, the\nname of the currently activated virtualenv is displayed on the command line to\nhelp you keep track of which one you are using. Go ahead and install the\npreviously cloned copy of Django:</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>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<p>The installed version of Django is now pointing at your local copy. You will\nimmediately see any changes you make to it, which is of great help when writing\nyour first patch.</p>\n</section>\n<section id=\"rolling-back-to-a-previous-revision-of-django\">\n<h2>Rolling back to a previous revision of Django<a class=\"heading-anchor\" href=\"#rolling-back-to-a-previous-revision-of-django\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>For this tutorial, we’ll be using ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> as a case study, so\nwe’ll rewind Django’s version history in git to before that ticket’s patch was\napplied. This will allow us to go through all of the steps involved in writing\nthat patch from scratch, including running Django’s test suite.</p>\n<p><strong>Keep in mind that while we’ll be using an older revision of Django’s trunk\nfor the purposes of the tutorial below, you should always use the current\ndevelopment revision of Django when working on your own patch for a ticket!</strong></p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>The patch for this ticket was written by Paweł Marczewski, and it was\napplied to Django as <a class=\"reference external\" href=\"https://github.com/django/django/commit/4df7e8483b2679fc1cba3410f08960bac6f51115\">commit 4df7e8483b2679fc1cba3410f08960bac6f51115</a>.\nConsequently, we’ll be using the revision of Django just prior to that,\n<a class=\"reference external\" href=\"https://github.com/django/django/commit/4ccfc4439a7add24f8db4ef3960d02ef8ae09887\">commit 4ccfc4439a7add24f8db4ef3960d02ef8ae09887</a>.</p>\n</aside>\n<p>Navigate into Django’s root directory (that’s the one that contains <code class=\"docutils literal notranslate\"><span class=\"pre\">django</span></code>,\n<code class=\"docutils literal notranslate\"><span class=\"pre\">docs</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">tests</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">AUTHORS</span></code>, etc.). You can then check out the older\nrevision of Django that we’ll be using in the tutorial below:</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>git<span class=\"w\"> </span>checkout<span class=\"w\"> </span>4ccfc4439a7add24f8db4ef3960d02ef8ae09887\n</code></pre></div>\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\nhaven’t completely broken Django. If you’ve never run Django’s test suite\nbefore, it’s a good idea to run it once beforehand just to get familiar with\nwhat its output is supposed to look like.</p>\n<p>Before running the test suite, install its dependencies by first <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code>-ing\ninto the Django <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> directory and then running:</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>pip<span class=\"w\"> </span>install<span class=\"w\"> </span>-r<span class=\"w\"> </span>requirements/py3.txt\n</code></pre></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=\"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<p>Now sit back and relax. Django’s entire test suite has over 9,600 different\ntests, so it can take anywhere from 5 to 15 minutes to run, depending on the\nspeed of your computer.</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’s run. <code class=\"docutils literal notranslate\"><span class=\"pre\">E</span></code> indicates that an error\nwas raised during a test, and <code class=\"docutils literal notranslate\"><span class=\"pre\">F</span></code> indicates that a test’s assertions failed.\nBoth of these are considered to be test failures. Meanwhile, <code class=\"docutils literal notranslate\"><span class=\"pre\">x</span></code> and <code class=\"docutils literal notranslate\"><span class=\"pre\">s</span></code>\nindicated 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/1.11/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/1.11/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/1.11/internals/contributing/writing-code/unit-tests/#running-unit-tests\"><span class=\"std std-ref\">Running the unit tests</span></a> for more information. If you’re using Python 3.5+,\nthere will be a couple failures related to deprecation warnings that you can\nignore. These failures have since been fixed in Django.</p>\n<p>Note that the latest Django trunk may not always be stable. When developing\nagainst trunk, you can check <a class=\"reference external\" href=\"https://djangoci.com\">Django’s continuous integration builds</a> to\ndetermine if the failures are specific to your machine or if they are also\npresent in Django’s official builds. If you click to view a particular build,\nyou can view the “Configuration Matrix” which shows failures broken down by\nPython 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/1.11/internals/contributing/writing-code/unit-tests/#running-unit-tests-settings\"><span class=\"std std-ref\">run the tests using a different database</span></a>.</p>\n</aside>\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=\"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_24788\n</code></pre></div>\n<p>You can choose any name that you want for the branch, “ticket_24788” 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-some-tests-for-ticket-24788\">\n<h3>Writing some tests for ticket #24788<a class=\"heading-anchor\" href=\"#writing-some-tests-for-ticket-24788\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> proposes a small feature addition: the ability to\nspecify the class level attribute <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> on Form classes, so that:</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>[…] forms which ship with apps could effectively namespace themselves such\nthat N overlapping form fields could be POSTed at once and resolved to the\ncorrect form.\n</code></pre></div>\n<p>In order to resolve this ticket, we’ll add a <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> attribute to the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> class. When creating instances of this class, passing a prefix to\nthe <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> method will still set that prefix on the created instance.\nBut not passing a prefix (or passing <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>) will use the class-level prefix.\nBefore we make those changes though, we’re going to write a couple tests to\nverify that our modification functions correctly and continues to function\ncorrectly in the future.</p>\n<p>Navigate to Django’s <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/forms_tests/tests/</span></code> folder and open the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">test_forms.py</span></code> file. Add the following code on line 1674 right before the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">test_forms_with_null_boolean</span></code> function:</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\">test_class_prefix</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"c1\"># Prefix can be also specified at the class level.</span>\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Person</span><span class=\"p\">(</span><span class=\"n\">Form</span><span class=\"p\">):</span>\n        <span class=\"n\">first_name</span> <span class=\"o\">=</span> <span class=\"n\">CharField</span><span class=\"p\">()</span>\n        <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"s1\">&#39;foo&#39;</span>\n\n    <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</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\">p</span><span class=\"o\">.</span><span class=\"n\">prefix</span><span class=\"p\">,</span> <span class=\"s1\">&#39;foo&#39;</span><span class=\"p\">)</span>\n\n    <span class=\"n\">p</span> <span class=\"o\">=</span> <span class=\"n\">Person</span><span class=\"p\">(</span><span class=\"n\">prefix</span><span class=\"o\">=</span><span class=\"s1\">&#39;bar&#39;</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\">p</span><span class=\"o\">.</span><span class=\"n\">prefix</span><span class=\"p\">,</span> <span class=\"s1\">&#39;bar&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>This new test checks that setting a class level prefix works as expected, and\nthat passing a <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> parameter when creating an instance still works too.</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/1.11/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=\"http://www.diveintopython3.net/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>Remember that we haven’t actually made any modifications to <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> yet,\nso our tests are going to fail. Let’s run all the tests in the <code class=\"docutils literal notranslate\"><span class=\"pre\">forms_tests</span></code>\nfolder to make sure that’s really what happens. From the command line, <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code>\ninto the Django <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> directory and run:</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>./runtests.py<span class=\"w\"> </span>forms_tests\n</code></pre></div>\n<p>If the tests ran correctly, you should see one failure corresponding to the test\nmethod we added. If all of the tests passed, then you’ll want to make sure that\nyou added the new test shown above to the appropriate folder and class.</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 functionality described in ticket <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/24788\">#24788</a> to\nDjango.</p>\n<section id=\"writing-the-code-for-ticket-24788\">\n<h3>Writing the code for ticket #24788<a class=\"heading-anchor\" href=\"#writing-the-code-for-ticket-24788\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Navigate to the <code class=\"docutils literal notranslate\"><span class=\"pre\">django/django/forms/</span></code> folder and open the <code class=\"docutils literal notranslate\"><span class=\"pre\">forms.py</span></code> file.\nFind the <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> class on line 72 and add the <code class=\"docutils literal notranslate\"><span class=\"pre\">prefix</span></code> class attribute\nright after the <code class=\"docutils literal notranslate\"><span class=\"pre\">field_order</span></code> attribute:</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\">class</span><span class=\"w\"> </span><span class=\"nc\">BaseForm</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"c1\"># This is the main implementation of all the Form logic. Note that this</span>\n    <span class=\"c1\"># class is different than Form. See the comments by the Form class for</span>\n    <span class=\"c1\"># more information. Any improvements to the form API should be made to</span>\n    <span class=\"c1\"># *this* class, not to the Form class.</span>\n    <span class=\"n\">field_order</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n    <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"kc\">None</span>\n</code></pre></div>\n</section>\n<section id=\"verifying-your-test-now-passes\">\n<h3>Verifying your test now passes<a class=\"heading-anchor\" href=\"#verifying-your-test-now-passes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Once you’re done modifying Django, we need to make sure that the tests we wrote\nearlier pass, so we can see whether the code we wrote above is working\ncorrectly. To run the tests in the <code class=\"docutils literal notranslate\"><span class=\"pre\">forms_tests</span></code> folder, <code class=\"docutils literal notranslate\"><span class=\"pre\">cd</span></code> into the\nDjango <code class=\"docutils literal notranslate\"><span class=\"pre\">tests/</span></code> directory and run:</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>./runtests.py<span class=\"w\"> </span>forms_tests\n</code></pre></div>\n<p>Oops, good thing we wrote those tests! You should still see one failure with\nthe following exception:</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\">AssertionError</span><span class=\"p\">:</span> <span class=\"kc\">None</span> <span class=\"o\">!=</span> <span class=\"s1\">&#39;foo&#39;</span>\n</code></pre></div>\n<p>We forgot to add the conditional statement in the <code class=\"docutils literal notranslate\"><span class=\"pre\">__init__</span></code> method. Go ahead\nand change <code class=\"docutils literal notranslate\"><span class=\"pre\">self.prefix</span> <span class=\"pre\">=</span> <span class=\"pre\">prefix</span></code> that is now on line 87 of\n<code class=\"docutils literal notranslate\"><span class=\"pre\">django/forms/forms.py</span></code>, adding a conditional statement:</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\">if</span> <span class=\"n\">prefix</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"kc\">None</span><span class=\"p\">:</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"n\">prefix</span>\n</code></pre></div>\n<p>Re-run the tests and everything should pass. If it doesn’t, make sure you\ncorrectly modified the <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseForm</span></code> class as shown above and copied the new test\ncorrectly.</p>\n</section>\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 just 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=\"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<p>As long as you don’t see any failures, you’re good to go.</p>\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. Add the following section on\nline 1068 (at the end of the file) of <code class=\"docutils literal notranslate\"><span class=\"pre\">django/docs/ref/forms/api.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>The prefix can also be specified on the form class::\n\n    &gt;&gt;&gt; class PersonForm(forms.Form):\n    ...     ...\n    ...     prefix = &#39;person&#39;\n\n.. versionadded:: 1.9\n\n    The ability to specify ``prefix`` on the form class was added.\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 Django 1.9, on line 164 under the “Forms” section in the file\n<code class=\"docutils literal notranslate\"><span class=\"pre\">docs/releases/1.9.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>* A form prefix can be specified inside a form class, not only when\n  instantiating a form. See :ref:`form-prefix` for details.\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/1.11/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 display the\ndifferences between your current copy of Django (with your changes) and the\nrevision that you initially checked out earlier in the tutorial:</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>git<span class=\"w\"> </span>diff\n</code></pre></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/forms/forms.py b/django/forms/forms.py</span>\n<span class=\"gh\">index 509709f..d1370de 100644</span>\n<span class=\"gd\">--- a/django/forms/forms.py</span>\n<span class=\"gi\">+++ b/django/forms/forms.py</span>\n<span class=\"gu\">@@ -75,6 +75,7 @@ class BaseForm(object):</span>\n<span class=\"w\"> </span>    # information. Any improvements to the form API should be made to *this*\n<span class=\"w\"> </span>    # class, not to the Form class.\n<span class=\"w\"> </span>    field_order = None\n<span class=\"gi\">+    prefix = None</span>\n\n<span class=\"w\"> </span>    def __init__(self, data=None, files=None, auto_id=&#39;id_%s&#39;, prefix=None,\n<span class=\"w\"> </span>                 initial=None, error_class=ErrorList, label_suffix=None,\n<span class=\"gu\">@@ -83,7 +84,8 @@ class BaseForm(object):</span>\n<span class=\"w\"> </span>        self.data = data or {}\n<span class=\"w\"> </span>        self.files = files or {}\n<span class=\"w\"> </span>        self.auto_id = auto_id\n<span class=\"gd\">-        self.prefix = prefix</span>\n<span class=\"gi\">+        if prefix is not None:</span>\n<span class=\"gi\">+            self.prefix = prefix</span>\n<span class=\"w\"> </span>        self.initial = initial or {}\n<span class=\"w\"> </span>        self.error_class = error_class\n<span class=\"w\"> </span>        # Translators: This is the default suffix added to form field labels\n<span class=\"gh\">diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt</span>\n<span class=\"gh\">index 3bc39cd..008170d 100644</span>\n<span class=\"gd\">--- a/docs/ref/forms/api.txt</span>\n<span class=\"gi\">+++ b/docs/ref/forms/api.txt</span>\n<span class=\"gu\">@@ -1065,3 +1065,13 @@ You can put several Django forms inside one ``&lt;form&gt;`` tag. To give each</span>\n<span class=\"w\"> </span>    &gt;&gt;&gt; print(father.as_ul())\n<span class=\"w\"> </span>    &lt;li&gt;&lt;label for=&quot;id_father-first_name&quot;&gt;First name:&lt;/label&gt; &lt;input type=&quot;text&quot; name=&quot;father-first_name&quot; id=&quot;id_father-first_name&quot; /&gt;&lt;/li&gt;\n<span class=\"w\"> </span>    &lt;li&gt;&lt;label for=&quot;id_father-last_name&quot;&gt;Last name:&lt;/label&gt; &lt;input type=&quot;text&quot; name=&quot;father-last_name&quot; id=&quot;id_father-last_name&quot; /&gt;&lt;/li&gt;\n<span class=\"gi\">+</span>\n<span class=\"gi\">+The prefix can also be specified on the form class::</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+    &gt;&gt;&gt; class PersonForm(forms.Form):</span>\n<span class=\"gi\">+    ...     ...</span>\n<span class=\"gi\">+    ...     prefix = &#39;person&#39;</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+.. versionadded:: 1.9</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+    The ability to specify ``prefix`` on the form class was added.</span>\n<span class=\"gh\">diff --git a/docs/releases/1.9.txt b/docs/releases/1.9.txt</span>\n<span class=\"gh\">index 5b58f79..f9bb9de 100644</span>\n<span class=\"gd\">--- a/docs/releases/1.9.txt</span>\n<span class=\"gi\">+++ b/docs/releases/1.9.txt</span>\n<span class=\"gu\">@@ -161,6 +161,9 @@ Forms</span>\n<span class=\"w\"> </span>  :attr:`~django.forms.Form.field_order` attribute, the ``field_order``\n<span class=\"w\"> </span>  constructor argument , or the :meth:`~django.forms.Form.order_fields` method.\n\n<span class=\"gi\">+* A form prefix can be specified inside a form class, not only when</span>\n<span class=\"gi\">+  instantiating a form. See :ref:`form-prefix` for details.</span>\n<span class=\"gi\">+</span>\n<span class=\"w\"> </span>Generic Views\n<span class=\"w\"> </span>^^^^^^^^^^^^^\n\n<span class=\"gh\">diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gh\">index 690f205..e07fae2 100644</span>\n<span class=\"gd\">--- a/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gi\">+++ b/tests/forms_tests/tests/test_forms.py</span>\n<span class=\"gu\">@@ -1671,6 +1671,18 @@ class FormsTestCase(SimpleTestCase):</span>\n<span class=\"w\"> </span>        self.assertEqual(p.cleaned_data[&#39;last_name&#39;], &#39;Lennon&#39;)\n<span class=\"w\"> </span>        self.assertEqual(p.cleaned_data[&#39;birthday&#39;], datetime.date(1940, 10, 9))\n\n<span class=\"gi\">+    def test_class_prefix(self):</span>\n<span class=\"gi\">+        # Prefix can be also specified at the class level.</span>\n<span class=\"gi\">+        class Person(Form):</span>\n<span class=\"gi\">+            first_name = CharField()</span>\n<span class=\"gi\">+            prefix = &#39;foo&#39;</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+        p = Person()</span>\n<span class=\"gi\">+        self.assertEqual(p.prefix, &#39;foo&#39;)</span>\n<span class=\"gi\">+</span>\n<span class=\"gi\">+        p = Person(prefix=&#39;bar&#39;)</span>\n<span class=\"gi\">+        self.assertEqual(p.prefix, &#39;bar&#39;)</span>\n<span class=\"gi\">+</span>\n<span class=\"w\"> </span>    def test_forms_with_null_boolean(self):\n<span class=\"w\"> </span>        # NullBooleanField is a bit of a special case because its presentation (widget)\n<span class=\"w\"> </span>        # is different than its data. This is handled transparently, though.\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=\"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<span class=\"w\"> </span>-a\n</code></pre></div>\n<p>This opens up a text editor to type the commit message. Follow the <a class=\"reference internal\" href=\"/en/1.11/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 #24788 -- Allowed Forms to specify a prefix at the class level.\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_24788” with the name of your branch if it’s different):</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>git<span class=\"w\"> </span>push<span class=\"w\"> </span>origin<span class=\"w\"> </span>ticket_24788\n</code></pre></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/1.11/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/1.11/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/1.11/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/1.11/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>. Just 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/1.11/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/1.11/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":"Rolling back to a previous revision of Django","anchor":"rolling-back-to-a-previous-revision-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":"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 some tests for ticket #24788","anchor":"writing-some-tests-for-ticket-24788","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":"Writing the code for ticket #24788","anchor":"writing-the-code-for-ticket-24788","children":[]},{"title":"Verifying your test now passes","anchor":"verifying-your-test-now-passes","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/1.11/intro/"}],"prev":{"docname":"intro/whatsnext","title":"What to read next","url":"/en/1.11/intro/whatsnext/"},"next":{"docname":"topics/index","title":"Using Django","url":"/en/1.11/topics/"},"formats":{"html":"/en/1.11/intro/contributing/","markdown":"/en/1.11/intro/contributing.md","json":"/en/1.11/intro/contributing.json"},"source":"https://github.com/django/django/blob/stable/1.11.x/docs/intro/contributing.txt","official":"https://docs.djangoproject.com/en/1.11/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","fr","ja","id","pt-br","ko","es","el","pl"]}