This guide aims to simplify the often daunting process of making your first contribution to Django. Drawing from a personal experience of navigating the documentation and successfully submitting a pull request, this tutorial offers a clear, step-by-step walkthrough. We’ll focus primarily on the Git and GitHub workflow, providing you with a solid foundation to confidently engage with the Django contribution ecosystem. For additional insights, such as interacting with Django’s ticket system, consider exploring Rim Choi’s blog post.
Here’s what we’ll cover:
- Setting up your local development environment
- Strategies for finding a suitable ticket to work on
- The process of working on your chosen ticket
- Navigating the essential contribution checklist
- Submitting your first pull request
Setting Up Your Local Environment
1. Obtaining Django’s Development Version
Begin by forking the Django repository on GitHub, as detailed in Django’s official contribution tutorial. Once forked, clone your copy to your local machine:
git clone https://github.com/YourGitHubName/django.git
Your personal fork will automatically be set as a remote named “origin.” Confirm this with:
git remote -v
Next, add the original Django repository as an “upstream” remote to easily sync with the main project. This is a common convention:
git remote add upstream https://github.com/django/django.git
Ensure your local Git configuration for this repository includes your username and email address, especially if you haven’t set them globally:
git config user.name <your name>git config user.email <your email>
2. Establishing a Virtual Environment
Following the contribution tutorial, create and activate a virtual environment. Inside this environment, install your local Django copy in editable mode:
pip install -e /path/to/your/local/clone/django/
Proceed to install Django’s test dependencies. Navigate to the tests directory and run:
cd testspip install -r requirements/py3.txt
Should the installation encounter issues, it might be due to missing system-level packages. For example, on Ubuntu 22.04, libmemcached-dev was required. Install any such dependencies and retry.
After successful installation, verify your setup by running Django’s test suite:
./runtests.py
Django’s documentation also has its own dependencies. Install them now by changing to the docs directory:
cd ../docspip install -r requirements.txt
Finally, return to the top-level Django directory and set up the pre-commit hooks, which help maintain code quality:
pip install pre-commitpre-commit install
Finding a Ticket to Work On
Identifying a beginner-friendly ticket can sometimes be tricky. While the “easy pickings” filter exists, these tickets are often quickly claimed. For your initial contribution, we recommend the “vulture strategy,” which involves improving existing patches. This approach allows you to focus on the contribution workflow rather than starting from scratch.
Django fellow Sarah Boyce suggests using these filters to find suitable tickets:
- Triage stage = Accepted
- Has patch = Yes
- Patch needs improvement = Yes
- Modified = between “-” and 6 months ago
- Type = Bug
You can further refine your search by grouping the results by component.
Once you’ve selected a ticket, assign it to yourself. If the ticket appears active, it’s good practice to leave a comment inquiring if you can take over. If there’s no response within 48 hours, proceed with assigning it to yourself. Refer to the “Claiming” tickets section for more details.
Working on Your Ticket
To begin, create a new local branch specifically for your ticket, based on the upstream main branch:
git checkout -b ticket_<ticket number> upstream/main
Since you’re improving an existing patch, you’ll need to apply it to your new branch. Always base your work on the most recent patch. Here’s a common method to apply a patch from a pull request:
curl -L https://github.com/django/django/pull/xxxxx.patch | git am
For detailed guidance, see Working on a patch.
When testing your changes and reproducing errors, utilize a Django test project, ensuring it operates within the same virtual environment where your editable Django copy is installed.
Upon making your changes, when you commit, the pre-commit hooks will activate. These hooks automatically format your code with Black and check for style compliance. You might need to re-stage files modified by the hooks or manually fix reported errors (e.g., excessively long comment lines) and then retry your commit.
Navigating the Contribution Checklist
Once you’ve refined the patch and addressed all feedback, it’s time to prepare your changes for a pull request by going through the contribution checklist. For bug fixes, most sections will be relevant, excluding those for new features or deprecations.
First, update your branch by rebasing it on the latest upstream main, if there have been any changes:
git fetch upstreamgit rebase upstream/main
Next, ensure the documentation builds without errors. From your local Django directory, navigate to docs and run:
cd docsmake html
Return to the top-level directory and confirm that the entire test suite passes:
cd tests./runtests.py
Squashing Commits
To maintain a clean commit history, squash your individual commits, along with those from previous contributors to the patch, into a single, cohesive commit. Determine how many commits you need to squash using:
git log -n 10 --oneline
If, for example, you need to squash three commits, use:
git rebase -i HEAD~3
In the editor that appears, retain pick for your final commit and change pick to squash for the preceding commits. After saving, a new editor will open with combined commit messages. Edit these to adhere to Django’s commit message format. Crucially, remember to credit co-authors from the original patch. An example format:
Fixed #35095 -- Clarified Swiss number formatting in docs/topics/i18n/formatting.txt.Co-Authored-By: Name <email@address>
Once squashed, push your single commit to your remote fork:
git push origin ticket_<ticket number>
If you need to correct a commit message after pushing, you can reword it:
git rebase -i HEAD~1
Change pick to reword, save, and then edit the message in the subsequent editor. If you’ve already pushed, you’ll need to force-push the corrected commit:
git push --force origin <your branch>
Final Steps for First-Time Contributors:
If this is your inaugural Django contribution, add your name to the AUTHORS file and submit a Contributor License Agreement.
Creating Your Pull Request
The final step is to create your pull request! Navigate to Django’s GitHub page, or directly use the URL structure: https://github.com/GITHUB_USERNAME/pull/new/BRANCH_NAME/, replacing GITHUB_USERNAME and BRANCH_NAME with your details.
Craft a clear and concise pull request description. Always mention the relevant ticket number. If your work builds upon a previous pull request, acknowledge it in the description. Refer to an example description for guidance.
After submission, confirm your ticket appears in the review queue.
Should any GitHub CI checks fail, click the three dots next to the failed test for detailed logs to diagnose the issue. For minor linting or formatting corrections, it’s generally acceptable to force-push a rewritten commit. However, avoid force-pushing for substantial changes, as it can complicate the review process.
The review process often involves several iterations: you’ll receive feedback, add more commits to your local branch, squash these new commits into a single review commit, and then push it to your remote branch.
If you ever feel stuck or need friendly assistance, the #contributing-getting-started channel on the Django Discord server is an excellent resource.
Keep going – your PR will get merged!