mirror of
https://github.com/django/django.git
synced 2025-01-10 10:26:34 +00:00
414 lines
17 KiB
Plaintext
414 lines
17 KiB
Plaintext
========================
|
||
Submitting contributions
|
||
========================
|
||
|
||
We're always grateful for contributions to Django's code. Indeed, bug reports
|
||
with associated contributions will get fixed *far* more quickly than those
|
||
without a solution.
|
||
|
||
.. _trivial-change:
|
||
|
||
Typo fixes and trivial documentation changes
|
||
============================================
|
||
|
||
If you are fixing a really trivial issue, for example changing a word in the
|
||
documentation, the preferred way to provide the patch is using GitHub pull
|
||
requests without a Trac ticket.
|
||
|
||
See the :doc:`working-with-git` for more details on how to use pull requests.
|
||
|
||
"Claiming" tickets
|
||
==================
|
||
|
||
In an open-source project with hundreds of contributors around the world, it's
|
||
important to manage communication efficiently so that work doesn't get
|
||
duplicated and contributors can be as effective as possible.
|
||
|
||
Hence, our policy is for contributors to "claim" tickets in order to let other
|
||
developers know that a particular bug or feature is being worked on.
|
||
|
||
If you have identified a contribution you want to make and you're capable of
|
||
fixing it (as measured by your coding ability, knowledge of Django internals
|
||
and time availability), claim it by following these steps:
|
||
|
||
* `Login using your GitHub account`_ or `create an account`_ in our ticket
|
||
system. If you have an account but have forgotten your password, you can
|
||
reset it using the `password reset page`_.
|
||
|
||
* If a ticket for this issue doesn't exist yet, create one in our
|
||
`ticket tracker`_.
|
||
|
||
* If a ticket for this issue already exists, make sure nobody else has
|
||
claimed it. To do this, look at the "Owned by" section of the ticket.
|
||
If it's assigned to "nobody," then it's available to be claimed.
|
||
Otherwise, somebody else may be working on this ticket. Either find another
|
||
bug/feature to work on, or contact the developer working on the ticket to
|
||
offer your help. If a ticket has been assigned for weeks or months without
|
||
any activity, it's probably safe to reassign it to yourself.
|
||
|
||
* Log into your account, if you haven't already, by clicking "GitHub Login"
|
||
or "DjangoProject Login" in the upper left of the ticket page. Once logged
|
||
in, you can then click the "Modify Ticket" button near the bottom of the
|
||
page.
|
||
|
||
* Claim the ticket by clicking the "assign to" radio button in the "Action"
|
||
section. Your username will be filled in the text box by default.
|
||
|
||
* Finally click the "Submit changes" button at the bottom to save.
|
||
|
||
.. note::
|
||
The Django software foundation requests that anyone contributing more than
|
||
a :ref:`trivial change <trivial-change>`, to Django sign and submit a
|
||
`Contributor License Agreement`_, this ensures that the Django Software
|
||
Foundation has clear license to all contributions allowing for a clear
|
||
license for all users.
|
||
|
||
.. _Login using your GitHub account: https://code.djangoproject.com/github/login
|
||
.. _Create an account: https://www.djangoproject.com/accounts/register/
|
||
.. _password reset page: https://www.djangoproject.com/accounts/password/reset/
|
||
.. _Contributor License Agreement: https://www.djangoproject.com/foundation/cla/
|
||
|
||
Ticket claimers' responsibility
|
||
-------------------------------
|
||
|
||
Once you've claimed a ticket, you have a responsibility to work on that ticket
|
||
in a reasonably timely fashion. If you don't have time to work on it, either
|
||
unclaim it or don't claim it in the first place!
|
||
|
||
If there's no sign of progress on a particular claimed ticket for a week or
|
||
two, another developer may ask you to relinquish the ticket claim so that it's
|
||
no longer monopolized and somebody else can claim it.
|
||
|
||
If you've claimed a ticket and it's taking a long time (days or weeks) to code,
|
||
keep everybody updated by posting comments on the ticket. If you don't provide
|
||
regular updates, and you don't respond to a request for a progress report,
|
||
your claim on the ticket may be revoked.
|
||
|
||
As always, more communication is better than less communication!
|
||
|
||
Which tickets should be claimed?
|
||
--------------------------------
|
||
|
||
Going through the steps of claiming tickets is overkill in some cases.
|
||
|
||
In the case of small changes, such as typos in the documentation or small bugs
|
||
that will only take a few minutes to fix, you don't need to jump through the
|
||
hoops of claiming tickets. Submit your changes directly and you're done!
|
||
|
||
It is *always* acceptable, regardless whether someone has claimed it or not, to
|
||
link proposals to a ticket if you happen to have the changes ready.
|
||
|
||
.. _patch-style:
|
||
|
||
Contribution style
|
||
==================
|
||
|
||
Make sure that any contribution you do fulfills at least the following
|
||
requirements:
|
||
|
||
* The code required to fix a problem or add a feature is an essential part
|
||
of a solution, but it is not the only part. A good fix should also include a
|
||
:doc:`regression test <unit-tests>` to validate the behavior that has been
|
||
fixed and to prevent the problem from arising again. Also, if some tickets
|
||
are relevant to the code that you've written, mention the ticket numbers in
|
||
some comments in the test so that one can easily trace back the relevant
|
||
discussions after your patch gets committed, and the tickets get closed.
|
||
|
||
* If the code adds a new feature, or modifies the behavior of an existing
|
||
feature, the change should also contain documentation.
|
||
|
||
When you think your work is ready to be reviewed, send :doc:`a GitHub pull
|
||
request <working-with-git>`.
|
||
If you can't send a pull request for some reason, you can also use patches in
|
||
Trac. When using this style, follow these guidelines.
|
||
|
||
* Submit patches in the format returned by the ``git diff`` command.
|
||
|
||
* Attach patches to a ticket in the `ticket tracker`_, using the "attach
|
||
file" button. Please *don't* put the patch in the ticket description
|
||
or comment unless it's a single line patch.
|
||
|
||
* Name the patch file with a ``.diff`` extension; this will let the ticket
|
||
tracker apply correct syntax highlighting, which is quite helpful.
|
||
|
||
Regardless of the way you submit your work, follow these steps.
|
||
|
||
* Make sure your code fulfills the requirements in our :ref:`contribution
|
||
checklist <patch-review-checklist>`.
|
||
|
||
* Check the "Has patch" box on the ticket and make sure the "Needs
|
||
documentation", "Needs tests", and "Patch needs improvement" boxes aren't
|
||
checked. This makes the ticket appear in the "Patches needing review" queue
|
||
on the `Development dashboard`_.
|
||
|
||
.. _ticket tracker: https://code.djangoproject.com/
|
||
.. _Development dashboard: https://dashboard.djangoproject.com/
|
||
|
||
Contributions which require community feedback
|
||
==============================================
|
||
|
||
A wider community discussion is required when a patch introduces new Django
|
||
functionality and makes some sort of design decision. This is especially
|
||
important if the approach involves a :ref:`deprecation <deprecating-a-feature>`
|
||
or introduces breaking changes.
|
||
|
||
The following are different approaches for gaining feedback from the community.
|
||
|
||
The Django Forum or django-developers mailing list
|
||
--------------------------------------------------
|
||
|
||
You can propose a change on the `Django Forum`_ or |django-developers| mailing
|
||
list. You should explain the need for the change, go into details of the
|
||
approach and discuss alternatives.
|
||
|
||
Please include a link to such discussions in your contributions.
|
||
|
||
Third party package
|
||
-------------------
|
||
|
||
Django does not accept experimental features. All features must follow our
|
||
:ref:`deprecation policy <internal-release-deprecation-policy>`. Hence, it can
|
||
take months or years for Django to iterate on an API design.
|
||
|
||
If you need user feedback on a public interface, it is better to create a
|
||
third-party package first. You can iterate on the public API much faster, while
|
||
also validating the need for the feature.
|
||
|
||
Once this package becomes stable and there are clear benefits of incorporating
|
||
aspects into Django core, starting a discussion on the `Django Forum`_ or
|
||
|django-developers| mailing list would be the next step.
|
||
|
||
Django Enhancement Proposal (DEP)
|
||
---------------------------------
|
||
|
||
Similar to Python’s PEPs, Django has `Django Enhancement Proposals`_ or DEPs. A
|
||
DEP is a design document which provides information to the Django community, or
|
||
describes a new feature or process for Django. They provide concise technical
|
||
specifications of features, along with rationales. DEPs are also the primary
|
||
mechanism for proposing and collecting community input on major new features.
|
||
|
||
Before considering writing a DEP, it is recommended to first open a discussion
|
||
on the `Django Forum`_ or |django-developers| mailing list. This allows the
|
||
community to provide feedback and helps refine the proposal. Once the DEP is
|
||
ready the :ref:`Steering Council <steering-council>` votes on whether to accept
|
||
it.
|
||
|
||
Some examples of DEPs that have been approved and fully implemented:
|
||
|
||
* `DEP 181: ORM Expressions <https://github.com/django/deps/blob/main/final/0181-orm-expressions.rst>`_
|
||
* `DEP 182: Multiple Template Engines <https://github.com/django/deps/blob/main/final/0182-multiple-template-engines.rst>`_
|
||
* `DEP 201: Simplified routing syntax <https://github.com/django/deps/blob/main/final/0201-simplified-routing-syntax.rst>`_
|
||
|
||
.. _Django Forum: https://forum.djangoproject.com/
|
||
.. _Django Enhancement Proposals: https://github.com/django/deps
|
||
|
||
.. _deprecating-a-feature:
|
||
|
||
Deprecating a feature
|
||
=====================
|
||
|
||
There are a couple of reasons that code in Django might be deprecated:
|
||
|
||
* If a feature has been improved or modified in a backwards-incompatible way,
|
||
the old feature or behavior will be deprecated.
|
||
|
||
* Sometimes Django will include a backport of a Python library that's not
|
||
included in a version of Python that Django currently supports. When Django
|
||
no longer needs to support the older version of Python that doesn't include
|
||
the library, the library will be deprecated in Django.
|
||
|
||
As the :ref:`deprecation policy<internal-release-deprecation-policy>` describes,
|
||
the first release of Django that deprecates a feature (``A.B``) should raise a
|
||
``RemovedInDjangoXXWarning`` (where XX is the Django version where the feature
|
||
will be removed) when the deprecated feature is invoked. Assuming we have good
|
||
test coverage, these warnings are converted to errors when :ref:`running the
|
||
test suite <running-unit-tests>` with warnings enabled:
|
||
``python -Wa runtests.py``. Thus, when adding a ``RemovedInDjangoXXWarning``
|
||
you need to eliminate or silence any warnings generated when running the tests.
|
||
|
||
The first step is to remove any use of the deprecated behavior by Django itself.
|
||
Next you can silence warnings in tests that actually test the deprecated
|
||
behavior by using the ``ignore_warnings`` decorator, either at the test or class
|
||
level:
|
||
|
||
#) In a particular test::
|
||
|
||
from django.test import ignore_warnings
|
||
from django.utils.deprecation import RemovedInDjangoXXWarning
|
||
|
||
|
||
@ignore_warnings(category=RemovedInDjangoXXWarning)
|
||
def test_foo(self): ...
|
||
|
||
#) For an entire test case::
|
||
|
||
from django.test import ignore_warnings
|
||
from django.utils.deprecation import RemovedInDjangoXXWarning
|
||
|
||
|
||
@ignore_warnings(category=RemovedInDjangoXXWarning)
|
||
class MyDeprecatedTests(unittest.TestCase): ...
|
||
|
||
You should also add a test for the deprecation warning::
|
||
|
||
from django.utils.deprecation import RemovedInDjangoXXWarning
|
||
|
||
|
||
def test_foo_deprecation_warning(self):
|
||
msg = "Expected deprecation message"
|
||
with self.assertWarnsMessage(RemovedInDjangoXXWarning, msg) as ctx:
|
||
# invoke deprecated behavior
|
||
...
|
||
self.assertEqual(ctx.filename, __file__)
|
||
|
||
It's important to include a ``RemovedInDjangoXXWarning`` comment above code
|
||
which has no warning reference, but will need to be changed or removed when the
|
||
deprecation ends. This could include hooks which have been added to keep the
|
||
previous behavior, or standalone items that are unnecessary or unused when the
|
||
deprecation ends. For example::
|
||
|
||
import warnings
|
||
from django.utils.deprecation import RemovedInDjangoXXWarning
|
||
|
||
|
||
# RemovedInDjangoXXWarning.
|
||
def old_private_helper():
|
||
# Helper function that is only used in foo().
|
||
pass
|
||
|
||
|
||
def foo():
|
||
warnings.warn(
|
||
"foo() is deprecated.",
|
||
category=RemovedInDjangoXXWarning,
|
||
stacklevel=2,
|
||
)
|
||
old_private_helper()
|
||
...
|
||
|
||
Finally, there are a couple of updates to Django's documentation to make:
|
||
|
||
#) If the existing feature is documented, mark it deprecated in documentation
|
||
using the ``.. deprecated:: A.B`` annotation. Include a short description
|
||
and a note about the upgrade path if applicable.
|
||
|
||
#) Add a description of the deprecated behavior, and the upgrade path if
|
||
applicable, to the current release notes (``docs/releases/A.B.txt``) under
|
||
the "Features deprecated in A.B" heading.
|
||
|
||
#) Add an entry in the deprecation timeline (``docs/internals/deprecation.txt``)
|
||
under the appropriate version describing what code will be removed.
|
||
|
||
Once you have completed these steps, you are finished with the deprecation.
|
||
In each :term:`feature release <Feature release>`, all
|
||
``RemovedInDjangoXXWarning``\s matching the new version are removed.
|
||
|
||
JavaScript contributions
|
||
========================
|
||
|
||
For information on JavaScript contributions, see the :ref:`javascript-patches`
|
||
documentation.
|
||
|
||
Optimization patches
|
||
====================
|
||
|
||
Patches aiming to deliver a performance improvement should provide benchmarks
|
||
showing the before and after impact of the patch and sharing the commands for
|
||
reviewers to reproduce.
|
||
|
||
.. _django-asv-benchmarks:
|
||
|
||
``django-asv`` benchmarks
|
||
-------------------------
|
||
|
||
`django-asv`_ monitors the performance of Django code over time. These
|
||
benchmarks can be run on a pull request by labeling the pull request with
|
||
``benchmark``. Adding to these benchmarks is highly encouraged.
|
||
|
||
.. _django-asv: https://github.com/django/django-asv/
|
||
|
||
.. _patch-review-checklist:
|
||
|
||
Contribution checklist
|
||
======================
|
||
|
||
Use this checklist to review a pull request. If this contribution would not be
|
||
:ref:`considered trivial <trivial-change>`, first ensure it has an accepted
|
||
ticket before proceeding with the review.
|
||
|
||
If the pull request passes all the criteria below and is not your own, please
|
||
set the "Triage Stage" on the corresponding Trac ticket to "Ready for checkin".
|
||
If you've left comments for improvement on the pull request, please tick the
|
||
appropriate flags on the Trac ticket based on the results of your review:
|
||
"Patch needs improvement", "Needs documentation", and/or "Needs tests". As time
|
||
and interest permits, mergers do final reviews of "Ready for checkin" tickets
|
||
and will either commit the changes or bump it back to "Accepted" if further
|
||
work needs to be done.
|
||
|
||
If you're looking to become a member of the `triage & review team
|
||
<https://www.djangoproject.com/foundation/teams/#triage-review-team>`_, doing
|
||
thorough reviews of contributions is a great way to earn trust.
|
||
|
||
Looking for a patch to review? Check out the "Patches needing review" section
|
||
of the `Django Development Dashboard <https://dashboard.djangoproject.com/>`_.
|
||
|
||
Looking to get your pull request reviewed? Ensure the Trac flags on the ticket
|
||
are set so that the ticket appears in that queue.
|
||
|
||
Documentation
|
||
-------------
|
||
|
||
* Does the documentation build without any errors (``make html``, or
|
||
``make.bat html`` on Windows, from the ``docs`` directory)?
|
||
* Does the documentation follow the writing style guidelines in
|
||
:doc:`/internals/contributing/writing-documentation`?
|
||
* Are there any :ref:`spelling errors <documentation-spelling-check>`?
|
||
|
||
Bugs
|
||
----
|
||
|
||
* Is there a proper regression test (the test should fail before the fix
|
||
is applied)?
|
||
* If it's a bug that :ref:`qualifies for a backport <supported-versions-policy>`
|
||
to the stable version of Django, is there a release note in
|
||
``docs/releases/A.B.C.txt``? Bug fixes that will be applied only to the main
|
||
branch don't need a release note.
|
||
|
||
New Features
|
||
------------
|
||
|
||
* Are there tests to "exercise" all of the new code?
|
||
* Is there a release note in ``docs/releases/A.B.txt``?
|
||
* Is there documentation for the feature and is it :ref:`annotated
|
||
appropriately <documenting-new-features>` with
|
||
``.. versionadded:: A.B`` or ``.. versionchanged:: A.B``?
|
||
|
||
Deprecating a feature
|
||
---------------------
|
||
|
||
See the :ref:`deprecating-a-feature` guide.
|
||
|
||
All code changes
|
||
----------------
|
||
|
||
* Does the :doc:`coding style
|
||
</internals/contributing/writing-code/coding-style>` conform to our
|
||
guidelines? Are there any ``black``, ``blacken-docs``, ``flake8``, or
|
||
``isort`` errors? You can install the :ref:`pre-commit
|
||
<coding-style-pre-commit>` hooks to automatically catch these errors.
|
||
* If the change is backwards incompatible in any way, is there a note
|
||
in the release notes (``docs/releases/A.B.txt``)?
|
||
* Is Django's test suite passing?
|
||
|
||
All tickets
|
||
-----------
|
||
|
||
* Is the pull request a single squashed commit with a message that follows our
|
||
:ref:`commit message format <committing-guidelines>`?
|
||
* Are you the patch author and a new contributor? Please add yourself to the
|
||
:source:`AUTHORS` file and submit a `Contributor License Agreement`_.
|
||
* Does this have an accepted ticket on Trac? All contributions require a ticket
|
||
unless the :ref:`change is considered trivial <trivial-change>`.
|
||
|
||
.. _Contributor License Agreement: https://www.djangoproject.com/foundation/cla/
|