mirror of
				https://github.com/django/django.git
				synced 2025-10-30 17:16:10 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			412 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			412 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
 | ||
| ----------------
 | ||
| 
 | ||
| You can propose a change on the `Django Forum`_. 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`_ 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`_. 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/
 |