Fixed #15796 -- Restructured the contributing documentation and added note about newly added Trac abilities. Many thanks to Julien Phalip.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16284 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
69cfee2f16
commit
407f62fd31
|
@ -1,321 +0,0 @@
|
||||||
===========================
|
|
||||||
How to contribute to Django
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Django is developed 100% by the community, and the more people that are actively
|
|
||||||
involved in the code the better Django will be. We recognize that contributing
|
|
||||||
to Django can be daunting at first and sometimes confusing even to
|
|
||||||
veterans. While we have our official "Contributing to Django" documentation
|
|
||||||
which spells out the technical details of triaging tickets and submitting
|
|
||||||
patches, it leaves a lot of room for interpretation. This guide aims to offer
|
|
||||||
more general advice on issues such as how to interpret the various stages and
|
|
||||||
flags in Trac, and how new contributors can get started.
|
|
||||||
|
|
||||||
.. seealso::
|
|
||||||
|
|
||||||
This guide is meant to answer the most common questions about
|
|
||||||
contributing to Django, however it is no substitute for the
|
|
||||||
:doc:`/internals/contributing` reference. Please make sure to
|
|
||||||
read that document to understand the specific details
|
|
||||||
involved in reporting issues and submitting patches.
|
|
||||||
|
|
||||||
.. _the-spirit-of-contributing:
|
|
||||||
|
|
||||||
"The Spirit of Contributing"
|
|
||||||
============================
|
|
||||||
|
|
||||||
Django uses Trac_ for managing our progress, and Trac is a community-tended
|
|
||||||
garden of the bugs people have found and the features people would like to see
|
|
||||||
added. As in any garden, sometimes there are weeds to be pulled and sometimes
|
|
||||||
there are flowers and vegetables that need picking. We need your help to sort
|
|
||||||
out one from the other, and in the end we all benefit together.
|
|
||||||
|
|
||||||
Like all gardens, we can aspire to perfection but in reality there's no such
|
|
||||||
thing. Even in the most pristine garden there are still snails and insects. In a
|
|
||||||
community garden there are also helpful people who--with the best of
|
|
||||||
intentions--fertilize the weeds and poison the roses. It's the job of the
|
|
||||||
community as a whole to self-manage, keep the problems to a minimum, and educate
|
|
||||||
those coming into the community so that they can become valuable contributing
|
|
||||||
members.
|
|
||||||
|
|
||||||
Similarly, while we aim for Trac to be a perfect representation of the state of
|
|
||||||
Django's progress, we acknowledge that this simply will not happen. By
|
|
||||||
distributing the load of Trac maintenance to the community, we accept that there
|
|
||||||
will be mistakes. Trac is "mostly accurate", and we give allowances for the fact
|
|
||||||
that sometimes it will be wrong. That's okay. We're perfectionists with
|
|
||||||
deadlines.
|
|
||||||
|
|
||||||
We rely on the community to keep participating, keep tickets as accurate as
|
|
||||||
possible, and raise issues for discussion on our mailing lists when there is
|
|
||||||
confusion or disagreement.
|
|
||||||
|
|
||||||
Django is a community project, and every contribution helps. We can't do this
|
|
||||||
without YOU!
|
|
||||||
|
|
||||||
.. _Trac: http://code.djangoproject.com/
|
|
||||||
|
|
||||||
Understanding Trac
|
|
||||||
==================
|
|
||||||
|
|
||||||
Trac is Django's sole official issue tracker. All known bugs, desired features
|
|
||||||
and ideas for changes are logged there.
|
|
||||||
|
|
||||||
However, Trac can be quite confusing even to veteran contributors. Having to
|
|
||||||
look at both flags and triage stages isn't immediately obvious, and the stages
|
|
||||||
themselves can be misinterpreted.
|
|
||||||
|
|
||||||
.. _triage-stages-explained:
|
|
||||||
|
|
||||||
What Django's triage stages "really mean"
|
|
||||||
-----------------------------------------
|
|
||||||
|
|
||||||
Unreviewed
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
The ticket has not been reviewed by anyone who felt qualified to make a judgment
|
|
||||||
about whether the ticket contained a valid issue, a viable feature, or ought to
|
|
||||||
be closed for any of the various reasons.
|
|
||||||
|
|
||||||
Accepted
|
|
||||||
~~~~~~~~
|
|
||||||
|
|
||||||
The big grey area! The absolute meaning of "accepted" is that the issue
|
|
||||||
described in the ticket is valid and is in some stage of being worked on. Beyond
|
|
||||||
that there are several considerations
|
|
||||||
|
|
||||||
|
|
||||||
* **Accepted + No Flags**
|
|
||||||
|
|
||||||
The ticket is valid, but no one has submitted a patch for it yet. Often this
|
|
||||||
means you could safely start writing a patch for it.
|
|
||||||
|
|
||||||
* **Accepted + Has Patch**
|
|
||||||
|
|
||||||
The ticket is waiting for people to review the supplied patch. This means
|
|
||||||
downloading the patch and trying it out, verifying that it contains tests and
|
|
||||||
docs, running the test suite with the included patch, and leaving feedback on
|
|
||||||
the ticket.
|
|
||||||
|
|
||||||
|
|
||||||
* **Accepted + Has Patch + (any other flag)**
|
|
||||||
|
|
||||||
This means the ticket has been reviewed, and has been found to need further
|
|
||||||
work. "Needs tests" and "Needs documentation" are self-explanatory. "Patch
|
|
||||||
needs improvement" will generally be accompanied by a comment on the ticket
|
|
||||||
explaining what is needed to improve the code.
|
|
||||||
|
|
||||||
Design Decision Needed
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
This stage is for issues which may be contentious, may be backwards
|
|
||||||
incompatible, or otherwise involve high-level design decisions. These decisions
|
|
||||||
are generally made by the core committers, however that is not a
|
|
||||||
requirement. See the FAQ below for "My ticket has been in DDN forever! What
|
|
||||||
should I do?"
|
|
||||||
|
|
||||||
Ready For Checkin
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The ticket was reviewed by any member of the community other than the person who
|
|
||||||
supplied the patch and found to meet all the requirements for a commit-ready
|
|
||||||
patch. A core committer now needs to give the patch a final review prior to
|
|
||||||
being committed. See the FAQ below for "My ticket has been in RFC forever! What
|
|
||||||
should I do?"
|
|
||||||
|
|
||||||
Someday/Maybe?
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Generally only used for vague/high-level features or design ideas. These tickets
|
|
||||||
are uncommon and overall less useful since they don't describe concrete
|
|
||||||
actionable issues.
|
|
||||||
|
|
||||||
Fixed on a branch
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Used to indicate that a ticket is resolved as part of a major body of work that
|
|
||||||
will eventually be merged to trunk. Tickets in this stage generally don't need
|
|
||||||
further work. This may happen in the case of major features/refactors in each
|
|
||||||
release cycle, or as part of the annual Google Summer of Code efforts.
|
|
||||||
|
|
||||||
.. _closing-tickets:
|
|
||||||
|
|
||||||
Closing Tickets
|
|
||||||
---------------
|
|
||||||
|
|
||||||
When a ticket has completed its useful lifecycle, it's time for it to be closed.
|
|
||||||
Closing a ticket is a big responsibility, though. You have to be sure that
|
|
||||||
the issue is really resolved, and you need to keep in mind that the reporter
|
|
||||||
of the ticket may not be happy to have their ticket closed (unless it's fixed,
|
|
||||||
of course). If you're not certain about closing a ticket, just leave a comment
|
|
||||||
with your thoughts instead.
|
|
||||||
|
|
||||||
If you do close a ticket, you should always make sure of the following:
|
|
||||||
|
|
||||||
* Be certain that the issue is resolved.
|
|
||||||
|
|
||||||
* Leave a comment explaining the decision to close the ticket.
|
|
||||||
|
|
||||||
* If there is a way they can improve the ticket to reopen it, let them know.
|
|
||||||
|
|
||||||
* If the ticket is a duplicate, reference the original ticket.
|
|
||||||
|
|
||||||
* **Be polite.** No one likes having their ticket closed. It can be
|
|
||||||
frustrating or even discouraging. The best way to avoid turning people
|
|
||||||
off from contributing to Django is to be polite and friendly and to offer
|
|
||||||
suggestions for how they could improve this ticket and other tickets in the
|
|
||||||
future.
|
|
||||||
|
|
||||||
.. seealso::
|
|
||||||
|
|
||||||
The :ref:`contributing reference <ticket-resolutions>` contains a
|
|
||||||
description of each of the available resolutions in Trac.
|
|
||||||
|
|
||||||
Example Trac workflow
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Here we see the life-cycle of an average ticket:
|
|
||||||
|
|
||||||
* Alice creates a ticket, and uploads an incomplete patch (no tests, incorrect
|
|
||||||
implementation).
|
|
||||||
|
|
||||||
* Bob reviews the patch, marks it "Accepted", "needs tests", and "patch needs
|
|
||||||
improvement", and leaves a comment telling Alice how the patch could be
|
|
||||||
improved.
|
|
||||||
|
|
||||||
* Alice updates the patch, adding tests (but not changing the
|
|
||||||
implementation). She removes the two flags.
|
|
||||||
|
|
||||||
* Charlie reviews the patch and resets the "patch needs improvement" flag with
|
|
||||||
another comment about improving the implementation.
|
|
||||||
|
|
||||||
* Alice updates the patch, fixing the implementation. She removes the "patch
|
|
||||||
needs improvement" flag.
|
|
||||||
|
|
||||||
* Daisy reviews the patch, and marks it RFC.
|
|
||||||
|
|
||||||
* Jacob reviews the RFC patch, applies it to his checkout, and commits it.
|
|
||||||
|
|
||||||
Some tickets require much less feedback than this, but then again some tickets
|
|
||||||
require much much more.
|
|
||||||
|
|
||||||
Advice for new contributors
|
|
||||||
===========================
|
|
||||||
|
|
||||||
New contributor and not sure what to do? Want to help but just don't know how to
|
|
||||||
get started? This is the section for you.
|
|
||||||
|
|
||||||
* **Pick a subject area that you care about, that you are familiar with, or that
|
|
||||||
you want to learn about.**
|
|
||||||
|
|
||||||
You don't already have to be an expert on the area you want to work on; you
|
|
||||||
become an expert through your ongoing contributions to the code.
|
|
||||||
|
|
||||||
* **Triage tickets.**
|
|
||||||
|
|
||||||
If a ticket is unreviewed and reports a bug, try and duplicate it. If you can
|
|
||||||
duplicate it and it seems valid, make a note that you confirmed the bug and
|
|
||||||
accept the ticket. Make sure the ticket is filed under the correct component
|
|
||||||
area. Consider writing a patch that adds a test for the bug's behavior, even
|
|
||||||
if you don't fix the bug itself.
|
|
||||||
|
|
||||||
* **Look for tickets that are accepted and review patches to build familiarity
|
|
||||||
with the codebase and the process.**
|
|
||||||
|
|
||||||
Mark the appropriate flags if a patch needs docs or tests. Look through the
|
|
||||||
changes a patch makes, and keep an eye out for syntax that is incompatible
|
|
||||||
with older but still supported versions of Python. Run the tests and make sure
|
|
||||||
they pass on your system. Where possible and relevant, try them out on a
|
|
||||||
database other than SQLite. Leave comments and feedback!
|
|
||||||
|
|
||||||
* **Keep old patches up to date.**
|
|
||||||
|
|
||||||
Oftentimes the codebase will change between a patch being submitted and the
|
|
||||||
time it gets reviewed. Make sure it still applies cleanly and functions as
|
|
||||||
expected. Simply updating a patch is both useful and important!
|
|
||||||
|
|
||||||
* **Trac isn't an absolute; the context is just as important as the words.**
|
|
||||||
|
|
||||||
When reading Trac, you need to take into account who says things, and when
|
|
||||||
they were said. Support for an idea two years ago doesn't necessarily mean
|
|
||||||
that the idea will still have support. You also need to pay attention to who
|
|
||||||
*hasn't* spoken -- for example, if a core team member hasn't been recently
|
|
||||||
involved in a discussion, then a ticket may not have the support required to
|
|
||||||
get into trunk.
|
|
||||||
|
|
||||||
* **Start small.**
|
|
||||||
|
|
||||||
It's easier to get feedback on a little issue than on a big one.
|
|
||||||
|
|
||||||
* **If you're going to engage in a big task, make sure that your idea has
|
|
||||||
support first.**
|
|
||||||
|
|
||||||
This means getting someone else to confirm that a bug is real before you fix
|
|
||||||
the issue, and ensuring that the core team supports a proposed feature before
|
|
||||||
you go implementing it.
|
|
||||||
|
|
||||||
* **Be bold! Leave feedback!**
|
|
||||||
|
|
||||||
Sometimes it can be scary to put your opinion out to the world and say "this
|
|
||||||
ticket is correct" or "this patch needs work", but it's the only way the
|
|
||||||
project moves forward. The contributions of the broad Django community
|
|
||||||
ultimately have a much greater impact than that of the core developers. We
|
|
||||||
can't do it without YOU!
|
|
||||||
|
|
||||||
* **Err on the side of caution when marking things Ready For Check-in.**
|
|
||||||
|
|
||||||
If you're really not certain if a ticket is ready, don't mark it as
|
|
||||||
such. Leave a comment instead, letting others know your thoughts. If you're
|
|
||||||
mostly certain, but not completely certain, you might also try asking on IRC
|
|
||||||
to see if someone else can confirm your suspicions.
|
|
||||||
|
|
||||||
* **Wait for feedback, and respond to feedback that you receive.**
|
|
||||||
|
|
||||||
Focus on one or two tickets, see them through from start to finish, and
|
|
||||||
repeat. The shotgun approach of taking on lots of tickets and letting some
|
|
||||||
fall by the wayside ends up doing more harm than good.
|
|
||||||
|
|
||||||
* **Be rigorous.**
|
|
||||||
|
|
||||||
When we say ":pep:`8`, and must have docs and tests", we mean it. If a patch
|
|
||||||
doesn't have docs and tests, there had better be a good reason. Arguments like
|
|
||||||
"I couldn't find any existing tests of this feature" don't carry much
|
|
||||||
weight--while it may be true, that means you have the extra-important job of
|
|
||||||
writing the very first tests for that feature, not that you get a pass from
|
|
||||||
writing tests altogether.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The `Reports page`_ contains links to many useful Trac queries, including
|
|
||||||
several that are useful for triaging tickets and reviewing patches as
|
|
||||||
suggested above.
|
|
||||||
|
|
||||||
.. _Reports page: http://code.djangoproject.com/wiki/Reports
|
|
||||||
|
|
||||||
|
|
||||||
FAQs
|
|
||||||
====
|
|
||||||
|
|
||||||
**This ticket I care about has been ignored for days/weeks/months! What can I do
|
|
||||||
to get it committed?**
|
|
||||||
|
|
||||||
* First off, it's not personal. Django is entirely developed by volunteers (even
|
|
||||||
the core devs), and sometimes folks just don't have time. The best thing to do
|
|
||||||
is to send a gentle reminder to the Django Developers mailing list asking for
|
|
||||||
review on the ticket, or to bring it up in the #django-dev IRC channel.
|
|
||||||
|
|
||||||
|
|
||||||
**I'm sure my ticket is absolutely 100% perfect, can I mark it as RFC myself?**
|
|
||||||
|
|
||||||
* Short answer: No. It's always better to get another set of eyes on a
|
|
||||||
ticket. If you're having trouble getting that second set of eyes, see question
|
|
||||||
1, above.
|
|
||||||
|
|
||||||
|
|
||||||
**My ticket has been in DDN forever! What should I do?**
|
|
||||||
|
|
||||||
* Design Decision Needed requires consensus about the right solution. At the
|
|
||||||
very least it needs consensus among the core developers, and ideally it has
|
|
||||||
consensus from the community as well. The best way to accomplish this is to
|
|
||||||
start a thread on the Django Developers mailing list, and for very complex
|
|
||||||
issues to start a wiki page summarizing the problem and the possible
|
|
||||||
solutions.
|
|
|
@ -11,7 +11,6 @@ you quickly accomplish common tasks.
|
||||||
|
|
||||||
apache-auth
|
apache-auth
|
||||||
auth-remote-user
|
auth-remote-user
|
||||||
contribute
|
|
||||||
custom-management-commands
|
custom-management-commands
|
||||||
custom-model-fields
|
custom-model-fields
|
||||||
custom-template-tags
|
custom-template-tags
|
||||||
|
|
|
@ -200,7 +200,7 @@ The Django open-source project
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
* **Community:**
|
* **Community:**
|
||||||
:doc:`How to get involved <internals/contributing>` |
|
:doc:`How to get involved <internals/contributing/index>` |
|
||||||
:doc:`The release process <internals/release-process>` |
|
:doc:`The release process <internals/release-process>` |
|
||||||
:doc:`Team of committers <internals/committers>` |
|
:doc:`Team of committers <internals/committers>` |
|
||||||
:doc:`The Django source code repository <internals/svn>`
|
:doc:`The Django source code repository <internals/svn>`
|
||||||
|
@ -209,7 +209,7 @@ The Django open-source project
|
||||||
:doc:`Overview <misc/design-philosophies>`
|
:doc:`Overview <misc/design-philosophies>`
|
||||||
|
|
||||||
* **Documentation:**
|
* **Documentation:**
|
||||||
:doc:`About this documentation <internals/documentation>`
|
:doc:`About this documentation <internals/contributing/writing-documentation>`
|
||||||
|
|
||||||
* **Third-party distributions:**
|
* **Third-party distributions:**
|
||||||
:doc:`Overview <misc/distributions>`
|
:doc:`Overview <misc/distributions>`
|
||||||
|
|
|
@ -58,6 +58,8 @@ Current developers
|
||||||
|
|
||||||
Currently, Django is led by a team of volunteers from around the globe.
|
Currently, Django is led by a team of volunteers from around the globe.
|
||||||
|
|
||||||
|
.. _django-bdfls:
|
||||||
|
|
||||||
BDFLs
|
BDFLs
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,181 @@
|
||||||
|
======================================
|
||||||
|
Reporting bugs and requesting features
|
||||||
|
======================================
|
||||||
|
|
||||||
|
Before reporting a bug or requesting a new feature please consider these
|
||||||
|
general points:
|
||||||
|
|
||||||
|
* Check that someone hasn't already filed the bug or feature request by
|
||||||
|
`searching`_ or running `custom queries`_ in the ticket tracker.
|
||||||
|
|
||||||
|
* Don't use the ticket system to ask support questions. Use the
|
||||||
|
`django-users`_ list, or the `#django`_ IRC channel for that.
|
||||||
|
|
||||||
|
* Don't reopen issues that have been marked "wontfix" by a core developer.
|
||||||
|
This mark means that the decision has been made that we can't or won't fix
|
||||||
|
this particular issue. If you're not sure why, please ask
|
||||||
|
on `django-developers`_.
|
||||||
|
|
||||||
|
* Don't use the ticket tracker for lengthy discussions, because they're
|
||||||
|
likely to get lost. If a particular ticket is controversial, please move
|
||||||
|
discussion to `django-developers`_.
|
||||||
|
|
||||||
|
.. _reporting-bugs:
|
||||||
|
|
||||||
|
Reporting bugs
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Well-written bug reports are *incredibly* helpful. However, there's a certain
|
||||||
|
amount of overhead involved in working with any bug tracking system so your
|
||||||
|
help in keeping our ticket tracker as useful as possible is appreciated. In
|
||||||
|
particular:
|
||||||
|
|
||||||
|
* **Do** read the :doc:`FAQ </faq/index>` to see if your issue might
|
||||||
|
be a well-known question.
|
||||||
|
|
||||||
|
* **Do** ask on `django-users`_ *first* if you're not sure if what you're
|
||||||
|
seeing is a bug.
|
||||||
|
|
||||||
|
* **Do** write complete, reproducible, specific bug reports. Include as
|
||||||
|
much information as you possibly can, complete with code snippets, test
|
||||||
|
cases, etc. This means including a clear, concise description of the
|
||||||
|
problem, and a clear set of instructions for replicating the problem.
|
||||||
|
A minimal example that illustrates the bug in a nice small test case
|
||||||
|
is the best possible bug report.
|
||||||
|
|
||||||
|
* **Don't** post to django-developers just to announce that you have filed
|
||||||
|
a bug report. All the tickets are mailed to another list
|
||||||
|
(`django-updates`_), which is tracked by developers and interested
|
||||||
|
community members; we see them as they are filed.
|
||||||
|
|
||||||
|
To understand the lifecycle of your ticket once you have created it, refer to
|
||||||
|
:doc:`triaging-tickets`.
|
||||||
|
|
||||||
|
.. _django-updates: http://groups.google.com/group/django-updates
|
||||||
|
|
||||||
|
.. _reporting-security-issues:
|
||||||
|
|
||||||
|
Reporting security issues
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
.. Important::
|
||||||
|
|
||||||
|
Please report security issues **only** to security@djangoproject.com.
|
||||||
|
This is a private list only open to long-time, highly trusted Django
|
||||||
|
developers, and its archives are not publicly readable.
|
||||||
|
|
||||||
|
In the event of a confirmed vulnerability in Django itself, we will take the
|
||||||
|
following actions:
|
||||||
|
|
||||||
|
* Acknowledge to the reporter that we've received the report and that a
|
||||||
|
fix is forthcoming. We'll give a rough timeline and ask the reporter
|
||||||
|
to keep the issue confidential until we announce it.
|
||||||
|
|
||||||
|
* Focus on developing a fix as quickly as possible and produce patches
|
||||||
|
against the current and two previous releases.
|
||||||
|
|
||||||
|
* Determine a go-public date for announcing the vulnerability and the fix.
|
||||||
|
To try to mitigate a possible "arms race" between those applying the
|
||||||
|
patch and those trying to exploit the hole, we will not announce
|
||||||
|
security problems immediately.
|
||||||
|
|
||||||
|
* Pre-notify third-party distributors of Django ("vendors"). We will send
|
||||||
|
these vendor notifications through private email which will include
|
||||||
|
documentation of the vulnerability, links to the relevant patch(es), and
|
||||||
|
a request to keep the vulnerability confidential until the official
|
||||||
|
go-public date.
|
||||||
|
|
||||||
|
* Publicly announce the vulnerability and the fix on the pre-determined
|
||||||
|
go-public date. This will probably mean a new release of Django, but
|
||||||
|
in some cases it may simply be patches against current releases.
|
||||||
|
|
||||||
|
Requesting features
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
We're always trying to make Django better, and your feature requests are a key
|
||||||
|
part of that. Here are some tips on how to make a request most effectively:
|
||||||
|
|
||||||
|
* First request the feature on `django-developers`_, not in the ticket
|
||||||
|
tracker. It'll get read more closely if it's on the mailing list.
|
||||||
|
|
||||||
|
* Describe clearly and concisely what the missing feature is and how you'd
|
||||||
|
like to see it implemented. Include example code (non-functional is OK)
|
||||||
|
if possible.
|
||||||
|
|
||||||
|
* Explain *why* you'd like the feature. In some cases this is obvious, but
|
||||||
|
since Django is designed to help real developers get real work done,
|
||||||
|
you'll need to explain it, if it isn't obvious why the feature would be
|
||||||
|
useful.
|
||||||
|
|
||||||
|
* Don't use the ticket system to make large-scale feature requests.
|
||||||
|
We like to discuss any big changes to Django's core on the
|
||||||
|
`django-developers`_ list before actually working on them.
|
||||||
|
|
||||||
|
As with most open-source projects, code talks. If you are willing to write the
|
||||||
|
code for the feature yourself or if (even better) you've already written it,
|
||||||
|
it's much more likely to be accepted. If it's a large feature that might need
|
||||||
|
multiple developers, we're always happy to give you an experimental branch in
|
||||||
|
our repository; see the :doc:`writing-code/branch-policy`.
|
||||||
|
|
||||||
|
To understand the lifecycle of your ticket once you have created it, refer to
|
||||||
|
:doc:`triaging-tickets`.
|
||||||
|
|
||||||
|
See also: :ref:`documenting-new-features`.
|
||||||
|
|
||||||
|
.. _how-we-make-decisions:
|
||||||
|
|
||||||
|
How we make decisions
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Whenever possible, we strive for a rough consensus. To that end, we'll often
|
||||||
|
have informal votes on `django-developers`_ about a feature. In these votes we
|
||||||
|
follow the voting style invented by Apache and used on Python itself, where
|
||||||
|
votes are given as +1, +0, -0, or -1. Roughly translated, these votes mean:
|
||||||
|
|
||||||
|
* +1: "I love the idea and I'm strongly committed to it."
|
||||||
|
|
||||||
|
* +0: "Sounds OK to me."
|
||||||
|
|
||||||
|
* -0: "I'm not thrilled, but I won't stand in the way."
|
||||||
|
|
||||||
|
* -1: "I strongly disagree and would be very unhappy to see the idea turn
|
||||||
|
into reality."
|
||||||
|
|
||||||
|
Although these votes on django-developers are informal, they'll be taken very
|
||||||
|
seriously. After a suitable voting period, if an obvious consensus arises
|
||||||
|
we'll follow the votes.
|
||||||
|
|
||||||
|
However, consensus is not always possible. If consensus cannot be reached, or
|
||||||
|
if the discussion towards a consensus fizzles out without a concrete decision,
|
||||||
|
we use a more formal process.
|
||||||
|
|
||||||
|
Any :doc:`core committer</internals/committers>` may call for a formal vote
|
||||||
|
using the same voting mechanism above. A proposition will be considered carried
|
||||||
|
by the core team if:
|
||||||
|
|
||||||
|
* There are three "+1" votes from members of the core team.
|
||||||
|
|
||||||
|
* There is no "-1" vote from any member of the core team.
|
||||||
|
|
||||||
|
* The :ref:`BDFLs<django-bdfls>` haven't stepped in and executed their
|
||||||
|
positive or negative veto.
|
||||||
|
|
||||||
|
When calling for a vote, the caller should specify a deadline by which
|
||||||
|
votes must be received. One week is generally suggested as the minimum
|
||||||
|
amount of time.
|
||||||
|
|
||||||
|
Since this process allows any core committer to veto a proposal, any "-1"
|
||||||
|
votes (or BDFL vetos) should be accompanied by an explanation that explains
|
||||||
|
what it would take to convert that "-1" into at least a "+0".
|
||||||
|
|
||||||
|
Whenever possible, these formal votes should be announced and held in
|
||||||
|
public on the `django-developers`_ mailing list. However, overly sensitive
|
||||||
|
or contentious issues -- including, most notably, votes on new core
|
||||||
|
committers -- may be held in private.
|
||||||
|
|
||||||
|
|
||||||
|
.. _searching: http://code.djangoproject.com/search
|
||||||
|
.. _`custom queries`: https://code.djangoproject.com/query
|
||||||
|
.. _django-developers: http://groups.google.com/group/django-developers
|
||||||
|
.. _django-users: http://groups.google.com/group/django-users
|
||||||
|
.. _`#django`: irc://irc.freenode.net/django
|
|
@ -0,0 +1,133 @@
|
||||||
|
===============
|
||||||
|
Committing code
|
||||||
|
===============
|
||||||
|
|
||||||
|
This section is addressed to the :doc:`/internals/committers` and to anyone
|
||||||
|
interested in knowing how code gets committed into Django core.
|
||||||
|
|
||||||
|
Commit access
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Django has two types of committers:
|
||||||
|
|
||||||
|
Core committers
|
||||||
|
These are people who have a long history of contributions to Django's
|
||||||
|
codebase, a solid track record of being polite and helpful on the
|
||||||
|
mailing lists, and a proven desire to dedicate serious time to Django's
|
||||||
|
development. The bar is high for full commit access.
|
||||||
|
|
||||||
|
Partial committers
|
||||||
|
These are people who are "domain experts." They have direct check-in
|
||||||
|
access to the subsystems that fall under their jurisdiction, and they're
|
||||||
|
given a formal vote in questions that involve their subsystems. This type
|
||||||
|
of access is likely to be given to someone who contributes a large
|
||||||
|
subframework to Django and wants to continue to maintain it.
|
||||||
|
|
||||||
|
Partial commit access is granted by the same process as full
|
||||||
|
committers. However, the bar is set lower; proven expertise in the area
|
||||||
|
in question is likely to be sufficient.
|
||||||
|
|
||||||
|
Decisions on new committers will follow the process explained in
|
||||||
|
:ref:`how-we-make-decisions`.
|
||||||
|
|
||||||
|
To request commit access, please contact an existing committer privately.
|
||||||
|
Public requests for commit access are potential flame-war starters, and
|
||||||
|
will be ignored.
|
||||||
|
|
||||||
|
Committing guidelines
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Please follow these guidelines when committing code to Django's Subversion
|
||||||
|
repository:
|
||||||
|
|
||||||
|
* For any medium-to-big changes, where "medium-to-big" is according to
|
||||||
|
your judgment, please bring things up on the `django-developers`_
|
||||||
|
mailing list before making the change.
|
||||||
|
|
||||||
|
If you bring something up on `django-developers`_ and nobody responds,
|
||||||
|
please don't take that to mean your idea is great and should be
|
||||||
|
implemented immediately because nobody contested it. Django's lead
|
||||||
|
developers don't have a lot of time to read mailing-list discussions
|
||||||
|
immediately, so you may have to wait a couple of days before getting a
|
||||||
|
response.
|
||||||
|
|
||||||
|
* Write detailed commit messages in the past tense, not present tense.
|
||||||
|
|
||||||
|
* Good: "Fixed Unicode bug in RSS API."
|
||||||
|
* Bad: "Fixes Unicode bug in RSS API."
|
||||||
|
* Bad: "Fixing Unicode bug in RSS API."
|
||||||
|
|
||||||
|
* For commits to a branch, prefix the commit message with the branch name.
|
||||||
|
For example: "magic-removal: Added support for mind reading."
|
||||||
|
|
||||||
|
* Limit commits to the most granular change that makes sense. This means,
|
||||||
|
use frequent small commits rather than infrequent large commits. For
|
||||||
|
example, if implementing feature X requires a small change to library Y,
|
||||||
|
first commit the change to library Y, then commit feature X in a
|
||||||
|
separate commit. This goes a *long way* in helping all core Django
|
||||||
|
developers follow your changes.
|
||||||
|
|
||||||
|
* Separate bug fixes from feature changes.
|
||||||
|
|
||||||
|
Bug fixes need to be added to the current bugfix branch (e.g. the
|
||||||
|
``1.0.X`` branch) as well as the current trunk.
|
||||||
|
|
||||||
|
* If your commit closes a ticket in the Django `ticket tracker`_, begin
|
||||||
|
your commit message with the text "Fixed #abc", where "abc" is the
|
||||||
|
number of the ticket your commit fixes. Example: "Fixed #123 -- Adde
|
||||||
|
support for foo". We've rigged Subversion and Trac so that any commit
|
||||||
|
message in that format will automatically close the referenced ticket
|
||||||
|
and post a comment to it with the full commit message.
|
||||||
|
|
||||||
|
If your commit closes a ticket and is in a branch, use the branch name
|
||||||
|
first, then the "Fixed #abc." For example:
|
||||||
|
"magic-removal: Fixed #123 -- Added whizbang feature."
|
||||||
|
|
||||||
|
For the curious: We're using a `Trac post-commit hook`_ for this.
|
||||||
|
|
||||||
|
.. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook
|
||||||
|
|
||||||
|
* If your commit references a ticket in the Django `ticket tracker`_ but
|
||||||
|
does *not* close the ticket, include the phrase "Refs #abc", where "abc"
|
||||||
|
is the number of the ticket your commit references. We've rigged
|
||||||
|
Subversion and Trac so that any commit message in that format will
|
||||||
|
automatically post a comment to the appropriate ticket.
|
||||||
|
|
||||||
|
Reverting commits
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Nobody's perfect; mistakes will be committed. When a mistaken commit is
|
||||||
|
discovered, please follow these guidelines:
|
||||||
|
|
||||||
|
* Try very hard to ensure that mistakes don't happen. Just because we
|
||||||
|
have a reversion policy doesn't relax your responsibility to aim for
|
||||||
|
the highest quality possible. Really: double-check your work before
|
||||||
|
you commit it in the first place!
|
||||||
|
|
||||||
|
* If possible, have the original author revert his/her own commit.
|
||||||
|
|
||||||
|
* Don't revert another author's changes without permission from the
|
||||||
|
original author.
|
||||||
|
|
||||||
|
* If the original author can't be reached (within a reasonable amount
|
||||||
|
of time -- a day or so) and the problem is severe -- crashing bug,
|
||||||
|
major test failures, etc -- then ask for objections on django-dev
|
||||||
|
then revert if there are none.
|
||||||
|
|
||||||
|
* If the problem is small (a feature commit after feature freeze,
|
||||||
|
say), wait it out.
|
||||||
|
|
||||||
|
* If there's a disagreement between the committer and the
|
||||||
|
reverter-to-be then try to work it out on the `django-developers`_
|
||||||
|
mailing list. If an agreement can't be reached then it should
|
||||||
|
be put to a vote.
|
||||||
|
|
||||||
|
* If the commit introduced a confirmed, disclosed security
|
||||||
|
vulnerability then the commit may be reverted immediately without
|
||||||
|
permission from anyone.
|
||||||
|
|
||||||
|
* The release branch maintainer may back out commits to the release
|
||||||
|
branch without permission if the commit breaks the release branch.
|
||||||
|
|
||||||
|
.. _django-developers: http://groups.google.com/group/django-developers
|
||||||
|
.. _ticket tracker: http://code.djangoproject.com/newticket
|
|
@ -0,0 +1,48 @@
|
||||||
|
======================
|
||||||
|
Contributing to Django
|
||||||
|
======================
|
||||||
|
|
||||||
|
If you think working *with* Django is fun, wait until you start working *on*
|
||||||
|
it. We're passionate about helping Django users make the jump to contributing
|
||||||
|
members of the community, so there are several ways you can help Django's
|
||||||
|
development:
|
||||||
|
|
||||||
|
* Blog about Django. We syndicate all the Django blogs we know about on
|
||||||
|
the `community page`_; if you'd like to see your blog on that page you
|
||||||
|
can `register it here`_.
|
||||||
|
|
||||||
|
* :doc:`Report bugs and request features<bugs-and-features>` in our
|
||||||
|
`ticket tracker`_.
|
||||||
|
|
||||||
|
* Join the `django-developers`_ mailing list and share your ideas for how
|
||||||
|
to improve Django. We're always open to suggestions.
|
||||||
|
|
||||||
|
* :doc:`Submit patches<writing-code/submitting-patches>` for new and/or
|
||||||
|
fixed behavior. If you're looking for an easy way to start contributing
|
||||||
|
to Django have a look at the `easy pickings`_ tickets.
|
||||||
|
|
||||||
|
* :doc:`Improve the documentation<writing-documentation>` or
|
||||||
|
:doc:`write unit tests<writing-code/unit-tests>`.
|
||||||
|
|
||||||
|
* :doc:`Triage tickets<triaging-tickets>` that have been created by other
|
||||||
|
users.
|
||||||
|
|
||||||
|
... and many more ways! Really, **ANYONE** can do something to help make
|
||||||
|
Django better and greater. Browse the following sections to find out how:
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
new-contributors
|
||||||
|
bugs-and-features
|
||||||
|
triaging-tickets
|
||||||
|
writing-code/index
|
||||||
|
writing-documentation
|
||||||
|
translations
|
||||||
|
committing-code
|
||||||
|
|
||||||
|
.. _django-developers: http://groups.google.com/group/django-developers
|
||||||
|
.. _ticket tracker: http://code.djangoproject.com/newticket
|
||||||
|
.. _community page: http://www.djangoproject.com/community/
|
||||||
|
.. _`easy pickings`: http://code.djangoproject.com/query?status=!closed&easy=1
|
||||||
|
.. _`register it here`: http://www.djangoproject.com/community/add/blogs/
|
|
@ -0,0 +1,137 @@
|
||||||
|
===========================
|
||||||
|
Advice for new contributors
|
||||||
|
===========================
|
||||||
|
|
||||||
|
New contributor and not sure what to do? Want to help but just don't know how
|
||||||
|
to get started? This is the section for you.
|
||||||
|
|
||||||
|
* **Pick a subject area that you care about, that you are familiar with, or
|
||||||
|
that you want to learn about**
|
||||||
|
|
||||||
|
You don't already have to be an expert on the area you want to work on; you
|
||||||
|
become an expert through your ongoing contributions to the code.
|
||||||
|
|
||||||
|
* **Triage tickets**
|
||||||
|
|
||||||
|
If a ticket is unreviewed and reports a bug, try and reproduce it. If you
|
||||||
|
can reproduce it and it seems valid, make a note that you confirmed the bug
|
||||||
|
and accept the ticket. Make sure the ticket is filed under the correct
|
||||||
|
component area. Consider writing a patch that adds a test for the bug's
|
||||||
|
behavior, even if you don't fix the bug itself. See more at
|
||||||
|
:ref:`how-can-i-help-with-triaging`
|
||||||
|
|
||||||
|
* **Look for tickets that are accepted and review patches to build familiarity
|
||||||
|
with the codebase and the process**
|
||||||
|
|
||||||
|
Mark the appropriate flags if a patch needs docs or tests. Look through the
|
||||||
|
changes a patch makes, and keep an eye out for syntax that is incompatible
|
||||||
|
with older but still supported versions of Python. Run the tests and make
|
||||||
|
sure they pass on your system. Where possible and relevant, try them out on
|
||||||
|
a database other than SQLite. Leave comments and feedback!
|
||||||
|
|
||||||
|
* **Keep old patches up to date**
|
||||||
|
|
||||||
|
Oftentimes the codebase will change between a patch being submitted and the
|
||||||
|
time it gets reviewed. Make sure it still applies cleanly and functions as
|
||||||
|
expected. Simply updating a patch is both useful and important! See more on
|
||||||
|
:doc:`writing-code/submitting-patches`.
|
||||||
|
|
||||||
|
* **Write some documentation**
|
||||||
|
|
||||||
|
Django's documentation is great but it can always be improved. Did you find
|
||||||
|
a typo? Do you think that something should be clarified? Go ahead and
|
||||||
|
suggest a documentation patch! See also the guide on
|
||||||
|
:doc:`writing-documentation`, in particular the tips for
|
||||||
|
:ref:`improving-the-documentation`.
|
||||||
|
|
||||||
|
* **Analyze the ticket's context and history**
|
||||||
|
|
||||||
|
Trac isn't an absolute; the context is just as important as the words.
|
||||||
|
When reading Trac, you need to take into account who says things, and when
|
||||||
|
they were said. Support for an idea two years ago doesn't necessarily mean
|
||||||
|
that the idea will still have support. You also need to pay attention to who
|
||||||
|
*hasn't* spoken -- for example, if a core team member hasn't been recently
|
||||||
|
involved in a discussion, then a ticket may not have the support required to
|
||||||
|
get into trunk.
|
||||||
|
|
||||||
|
* **Start small**
|
||||||
|
|
||||||
|
It's easier to get feedback on a little issue than on a big one. See the
|
||||||
|
`easy pickings`_.
|
||||||
|
|
||||||
|
* **If you're going to engage in a big task, make sure that your idea has
|
||||||
|
support first**
|
||||||
|
|
||||||
|
This means getting someone else to confirm that a bug is real before you fix
|
||||||
|
the issue, and ensuring that the core team supports a proposed feature
|
||||||
|
before you go implementing it.
|
||||||
|
|
||||||
|
* **Be bold! Leave feedback!**
|
||||||
|
|
||||||
|
Sometimes it can be scary to put your opinion out to the world and say "this
|
||||||
|
ticket is correct" or "this patch needs work", but it's the only way the
|
||||||
|
project moves forward. The contributions of the broad Django community
|
||||||
|
ultimately have a much greater impact than that of the core developers. We
|
||||||
|
can't do it without YOU!
|
||||||
|
|
||||||
|
* **Err on the side of caution when marking things Ready For Check-in**
|
||||||
|
|
||||||
|
If you're really not certain if a ticket is ready, don't mark it as
|
||||||
|
such. Leave a comment instead, letting others know your thoughts. If you're
|
||||||
|
mostly certain, but not completely certain, you might also try asking on IRC
|
||||||
|
to see if someone else can confirm your suspicions.
|
||||||
|
|
||||||
|
* **Wait for feedback, and respond to feedback that you receive**
|
||||||
|
|
||||||
|
Focus on one or two tickets, see them through from start to finish, and
|
||||||
|
repeat. The shotgun approach of taking on lots of tickets and letting some
|
||||||
|
fall by the wayside ends up doing more harm than good.
|
||||||
|
|
||||||
|
* **Be rigorous**
|
||||||
|
|
||||||
|
When we say ":pep:`8`, and must have docs and tests", we mean it. If a patch
|
||||||
|
doesn't have docs and tests, there had better be a good reason. Arguments
|
||||||
|
like "I couldn't find any existing tests of this feature" don't carry much
|
||||||
|
weight--while it may be true, that means you have the extra-important job of
|
||||||
|
writing the very first tests for that feature, not that you get a pass from
|
||||||
|
writing tests altogether.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The `Reports page`_ contains links to many useful Trac queries, including
|
||||||
|
several that are useful for triaging tickets and reviewing patches as
|
||||||
|
suggested above.
|
||||||
|
|
||||||
|
.. _Reports page: http://code.djangoproject.com/wiki/Reports
|
||||||
|
|
||||||
|
.. _new-contributors-faq:
|
||||||
|
|
||||||
|
FAQ
|
||||||
|
---
|
||||||
|
|
||||||
|
1. **This ticket I care about has been ignored for days/weeks/months! What can
|
||||||
|
I do to get it committed?**
|
||||||
|
|
||||||
|
First off, it's not personal. Django is entirely developed by volunteers
|
||||||
|
(even the core developers), and sometimes folks just don't have time. The
|
||||||
|
best thing to do is to send a gentle reminder to the Django Developers
|
||||||
|
mailing list asking for review on the ticket, or to bring it up in the
|
||||||
|
#django-dev IRC channel.
|
||||||
|
|
||||||
|
2. **I'm sure my ticket is absolutely 100% perfect, can I mark it as RFC
|
||||||
|
myself?**
|
||||||
|
|
||||||
|
Short answer: No. It's always better to get another set of eyes on a
|
||||||
|
ticket. If you're having trouble getting that second set of eyes, see
|
||||||
|
question 1, above.
|
||||||
|
|
||||||
|
3. **My ticket has been in DDN forever! What should I do?**
|
||||||
|
|
||||||
|
Design Decision Needed requires consensus about the right solution. At the
|
||||||
|
very least it needs consensus among the core developers, and ideally it has
|
||||||
|
consensus from the community as well. The best way to accomplish this is to
|
||||||
|
start a thread on the Django Developers mailing list, and for very complex
|
||||||
|
issues to start a wiki page summarizing the problem and the possible
|
||||||
|
solutions.
|
||||||
|
|
||||||
|
.. _`easy pickings`: http://code.djangoproject.com/query?status=!closed&easy=1
|
|
@ -0,0 +1,60 @@
|
||||||
|
=======================================
|
||||||
|
Submitting and maintaining translations
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
Various parts of Django, such as the admin site and validation error messages,
|
||||||
|
are internationalized. This means they display different text depending on a
|
||||||
|
user's language setting. For this, Django uses the same internationalization
|
||||||
|
infrastructure available to Django applications described in the
|
||||||
|
:doc:`i18n documentation</topics/i18n/index>`.
|
||||||
|
|
||||||
|
These translations are contributed by Django users worldwide. If you find an
|
||||||
|
incorrect translation or want to discuss specific translations, go to the
|
||||||
|
`translation team`_ page for that language. If you would like to help out
|
||||||
|
with translating or add a language that isn't yet translated, here's what
|
||||||
|
to do:
|
||||||
|
|
||||||
|
* Join the `Django i18n mailing list`_ and introduce yourself.
|
||||||
|
|
||||||
|
* Make sure you read the notes about :ref:`specialties-of-django-i18n`.
|
||||||
|
|
||||||
|
* Signup at `Transifex`_ and visit the `Django project page`_.
|
||||||
|
|
||||||
|
* On the "`Translation Teams`_" page, choose the language team you want
|
||||||
|
to work with, **or** -- in case the language team doesn't exist yet --
|
||||||
|
request a new team by clicking on the "Request a new team" button
|
||||||
|
and select the appropriate language.
|
||||||
|
|
||||||
|
* Then, click the "Join this Team" button to become a member of this team.
|
||||||
|
Every team has at least one coordinator who is responsible to review
|
||||||
|
your membership request. You can of course also contact the team
|
||||||
|
coordinator to clarify procedural problems and handle the actual
|
||||||
|
translation process.
|
||||||
|
|
||||||
|
* Once you are a member of a team choose the translation resource you
|
||||||
|
want to update on the team page. For example the "core" resource refers
|
||||||
|
to the translation catalogue that contains all non-contrib translations.
|
||||||
|
Each of the contrib apps also have a resource (prefixed with "contrib").
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
For more information about how to use Transifex, see the
|
||||||
|
`Transifex Help`_
|
||||||
|
|
||||||
|
* Optionally, review and update the ``conf/locale/<locale>/formats.py``
|
||||||
|
file to describe the date, time and numbers formatting particularities
|
||||||
|
of your locale. These files aren't covered by the use of Transifex and
|
||||||
|
require a patch against the Django source tree, just as a code change
|
||||||
|
would:
|
||||||
|
|
||||||
|
* Create a diff against the current Subversion trunk.
|
||||||
|
|
||||||
|
* Open a ticket in Django's ticket system, set its ``Component`` field
|
||||||
|
to ``Translations``, and attach the patch to it. See
|
||||||
|
:ref:`format-localization` for details.
|
||||||
|
|
||||||
|
.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
|
||||||
|
.. _Transifex: http://www.transifex.net/
|
||||||
|
.. _Django project page: http://www.transifex.net/projects/p/django/
|
||||||
|
.. _translation teams: http://www.transifex.net/projects/p/django/teams/
|
||||||
|
.. _translation team: http://www.transifex.net/projects/p/django/teams/
|
||||||
|
.. _Transifex Help: http://help.transifex.net/
|
|
@ -0,0 +1,389 @@
|
||||||
|
================
|
||||||
|
Triaging tickets
|
||||||
|
================
|
||||||
|
|
||||||
|
Django uses Trac_ for managing our progress, and Trac is a community-tended
|
||||||
|
garden of the bugs people have found and the features people would like to see
|
||||||
|
added. As in any garden, sometimes there are weeds to be pulled and sometimes
|
||||||
|
there are flowers and vegetables that need picking. We need your help to sort
|
||||||
|
out one from the other, and in the end we all benefit together.
|
||||||
|
|
||||||
|
Like all gardens, we can aspire to perfection but in reality there's no such
|
||||||
|
thing. Even in the most pristine garden there are still snails and insects.
|
||||||
|
In a community garden there are also helpful people who--with the best of
|
||||||
|
intentions--fertilize the weeds and poison the roses. It's the job of the
|
||||||
|
community as a whole to self-manage, keep the problems to a minimum, and
|
||||||
|
educate those coming into the community so that they can become valuable
|
||||||
|
contributing members.
|
||||||
|
|
||||||
|
Similarly, while we aim for Trac to be a perfect representation of the state
|
||||||
|
of Django's progress, we acknowledge that this simply will not happen. By
|
||||||
|
distributing the load of Trac maintenance to the community, we accept that
|
||||||
|
there will be mistakes. Trac is "mostly accurate", and we give allowances for
|
||||||
|
the fact that sometimes it will be wrong. That's okay. We're perfectionists
|
||||||
|
with deadlines.
|
||||||
|
|
||||||
|
We rely on the community to keep participating, keep tickets as accurate as
|
||||||
|
possible, and raise issues for discussion on our mailing lists when there is
|
||||||
|
confusion or disagreement.
|
||||||
|
|
||||||
|
Django is a community project, and every contribution helps. We can't do this
|
||||||
|
without YOU!
|
||||||
|
|
||||||
|
Triage workflow
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Unfortunately, not all bug reports and feature requests in the ticket tracker
|
||||||
|
provide all the :doc:`required details<bugs-and-features>`. A number of
|
||||||
|
tickets have patches, but those patches don't meet all the requirements of a
|
||||||
|
:ref:`good patch<patch-style>`.
|
||||||
|
|
||||||
|
One way to help out is to *triage* tickets that have been created by other
|
||||||
|
users. The core team--as well as many community members--work on this
|
||||||
|
regularly, but more help is always appreciated.
|
||||||
|
|
||||||
|
Most of the workflow is based around the concept of a ticket's
|
||||||
|
:ref:`triage stages <triage-stages>`. Each stage describes where in its
|
||||||
|
lifetime a given ticket is at any time. Along with a handful of flags, this
|
||||||
|
attribute easily tells us what and who each ticket is waiting on.
|
||||||
|
|
||||||
|
Since a picture is worth a thousand words, let's start there:
|
||||||
|
|
||||||
|
.. image:: /internals/_images/djangotickets.png
|
||||||
|
:height: 451
|
||||||
|
:width: 590
|
||||||
|
:alt: Django's ticket triage workflow
|
||||||
|
|
||||||
|
We've got two roles in this diagram:
|
||||||
|
|
||||||
|
* :doc:`Committers</internals/committers>` (also called core developers):
|
||||||
|
people with commit access who are responsible for making the big
|
||||||
|
decisions, writing large portions of the code and integrating the
|
||||||
|
contributions of the community.
|
||||||
|
|
||||||
|
* Ticket triagers: anyone in the Django community who chooses to
|
||||||
|
become involved in Django's development process. Our Trac installation
|
||||||
|
is intentionally left open to the public, and anyone can triage tickets.
|
||||||
|
Django is a community project, and we encourage :ref:`triage by the
|
||||||
|
community<how-can-i-help-with-triaging>`.
|
||||||
|
|
||||||
|
By way of example, here we see the lifecycle of an average ticket:
|
||||||
|
|
||||||
|
* Alice creates a ticket, and uploads an incomplete patch (no tests, incorrect
|
||||||
|
implementation).
|
||||||
|
|
||||||
|
* Bob reviews the patch, marks it "Accepted", "needs tests", and "patch needs
|
||||||
|
improvement", and leaves a comment telling Alice how the patch could be
|
||||||
|
improved.
|
||||||
|
|
||||||
|
* Alice updates the patch, adding tests (but not changing the
|
||||||
|
implementation). She removes the two flags.
|
||||||
|
|
||||||
|
* Charlie reviews the patch and resets the "patch needs improvement" flag with
|
||||||
|
another comment about improving the implementation.
|
||||||
|
|
||||||
|
* Alice updates the patch, fixing the implementation. She removes the "patch
|
||||||
|
needs improvement" flag.
|
||||||
|
|
||||||
|
* Daisy reviews the patch, and marks it RFC.
|
||||||
|
|
||||||
|
* Jacob, a core developer, reviews the RFC patch, applies it to his checkout,
|
||||||
|
and commits it.
|
||||||
|
|
||||||
|
Some tickets require much less feedback than this, but then again some tickets
|
||||||
|
require much much more.
|
||||||
|
|
||||||
|
.. _triage-stages:
|
||||||
|
|
||||||
|
Triage stages
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Below we describe in more detail the various stages that a ticket may flow
|
||||||
|
through during its lifetime.
|
||||||
|
|
||||||
|
Unreviewed
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
The ticket has not been reviewed by anyone who felt qualified to make a
|
||||||
|
judgment about whether the ticket contained a valid issue, a viable feature,
|
||||||
|
or ought to be closed for any of the various reasons.
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
The big grey area! The absolute meaning of "accepted" is that the issue
|
||||||
|
described in the ticket is valid and is in some stage of being worked on.
|
||||||
|
Beyond that there are several considerations:
|
||||||
|
|
||||||
|
* **Accepted + No Flags**
|
||||||
|
|
||||||
|
The ticket is valid, but no one has submitted a patch for it yet. Often this
|
||||||
|
means you could safely start writing a patch for it.
|
||||||
|
|
||||||
|
* **Accepted + Has Patch**
|
||||||
|
|
||||||
|
The ticket is waiting for people to review the supplied patch. This means
|
||||||
|
downloading the patch and trying it out, verifying that it contains tests
|
||||||
|
and docs, running the test suite with the included patch, and leaving
|
||||||
|
feedback on the ticket.
|
||||||
|
|
||||||
|
* **Accepted + Has Patch + (any other flag)**
|
||||||
|
|
||||||
|
This means the ticket has been reviewed, and has been found to need further
|
||||||
|
work. "Needs tests" and "Needs documentation" are self-explanatory. "Patch
|
||||||
|
needs improvement" will generally be accompanied by a comment on the ticket
|
||||||
|
explaining what is needed to improve the code.
|
||||||
|
|
||||||
|
Design Decision Needed
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
This stage is for issues which may be contentious, may be backwards
|
||||||
|
incompatible, or otherwise involve high-level design decisions. These issues
|
||||||
|
should be discussed either in the ticket comments or on `django-developers`_.
|
||||||
|
|
||||||
|
If a ticket has been marked as "DDN", decisions are generally eventually
|
||||||
|
made by the core committers, however that is not a requirement. See the
|
||||||
|
:ref:`New contributors' FAQ<new-contributors-faq>` for "My ticket has been in
|
||||||
|
DDN forever! What should I do?"
|
||||||
|
|
||||||
|
This stage will generally only be used for feature
|
||||||
|
requests. It can also be used for issues that *might* be bugs, depending on
|
||||||
|
opinion or interpretation. Obvious bugs (such as crashes, incorrect query
|
||||||
|
results, or non-compliance with a standard) skip this stage and move straight
|
||||||
|
to "Accepted".
|
||||||
|
|
||||||
|
Ready For Checkin
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The ticket was reviewed by any member of the community other than the person
|
||||||
|
who supplied the patch and found to meet all the requirements for a
|
||||||
|
commit-ready patch. A core committer now needs to give the patch a final
|
||||||
|
review prior to being committed. See the
|
||||||
|
:ref:`New contributors' FAQ<new-contributors-faq>` for "My ticket has been in
|
||||||
|
RFC forever! What should I do?"
|
||||||
|
|
||||||
|
Someday/Maybe
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Generally only used for vague/high-level features or design ideas. These
|
||||||
|
tickets are uncommon and overall less useful since they don't describe
|
||||||
|
concrete actionable issues. They are enhancement requests that we might
|
||||||
|
consider adding someday to the framework if an excellent patch is submitted.
|
||||||
|
These tickets are not a high priority.
|
||||||
|
|
||||||
|
Fixed on a branch
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Used to indicate that a ticket is resolved as part of a major body of work
|
||||||
|
that will eventually be merged to trunk. Tickets in this stage generally
|
||||||
|
don't need further work. This may happen in the case of major
|
||||||
|
features/refactors in each release cycle, or as part of the annual Google
|
||||||
|
Summer of Code efforts.
|
||||||
|
|
||||||
|
Other triage attributes
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
A number of flags, appearing as checkboxes in Trac, can be set on a ticket:
|
||||||
|
|
||||||
|
* Has patch
|
||||||
|
This means the ticket has an associated
|
||||||
|
:doc:`patch<writing-code/submitting-patches>`. These will be reviewed
|
||||||
|
to see if the patch is "good".
|
||||||
|
* Needs documentation:
|
||||||
|
This flag is used for tickets with patches that need associated
|
||||||
|
documentation. Complete documentation of features is a prerequisite
|
||||||
|
before we can check them into the codebase.
|
||||||
|
* Needs tests
|
||||||
|
This flags the patch as needing associated unit tests. Again, this
|
||||||
|
is a required part of a valid patch.
|
||||||
|
* Patch needs improvement
|
||||||
|
This flag means that although the ticket *has* a patch, it's not quite
|
||||||
|
ready for checkin. This could mean the patch no longer applies
|
||||||
|
cleanly, there is a flaw in the implementation, or that the code
|
||||||
|
doesn't meet our standards."
|
||||||
|
* Easy pickings
|
||||||
|
Tickets that would require small, easy, patches.
|
||||||
|
|
||||||
|
Tickets should be categorized by *type* between:
|
||||||
|
|
||||||
|
* New Feature
|
||||||
|
For adding something new.
|
||||||
|
|
||||||
|
* Bug
|
||||||
|
For when an existing thing is broken or not behaving as expected.
|
||||||
|
|
||||||
|
* Cleanup/optimization
|
||||||
|
For when nothing is broken but something could be made cleaner,
|
||||||
|
better, faster, stronger.
|
||||||
|
|
||||||
|
Tickets should also be classified into *components* indicating which area of
|
||||||
|
the Django codebase they belong to. This makes tickets better organized and
|
||||||
|
easier to find.
|
||||||
|
|
||||||
|
The *severity* attribute is used to identify blockers, that is, issues which
|
||||||
|
should get fixed before releasing the next version of Django. Typically those
|
||||||
|
issues are bugs causing regressions from earlier versions or potentially
|
||||||
|
causing severe data losses. This attribute is quite rarely used and the vast
|
||||||
|
majority of tickets have a severity of "Normal".
|
||||||
|
|
||||||
|
Finally, it is possible to use the *version* attribute to indicate in which
|
||||||
|
version the reported bug was identified.
|
||||||
|
|
||||||
|
.. _closing-tickets:
|
||||||
|
|
||||||
|
Closing Tickets
|
||||||
|
---------------
|
||||||
|
|
||||||
|
When a ticket has completed its useful lifecycle, it's time for it to be
|
||||||
|
closed. Closing a ticket is a big responsibility, though. You have to be sure
|
||||||
|
that the issue is really resolved, and you need to keep in mind that the
|
||||||
|
reporter of the ticket may not be happy to have their ticket closed (unless
|
||||||
|
it's fixed, of course). If you're not certain about closing a ticket, just
|
||||||
|
leave a comment with your thoughts instead.
|
||||||
|
|
||||||
|
If you do close a ticket, you should always make sure of the following:
|
||||||
|
|
||||||
|
* Be certain that the issue is resolved.
|
||||||
|
|
||||||
|
* Leave a comment explaining the decision to close the ticket.
|
||||||
|
|
||||||
|
* If there is a way they can improve the ticket to reopen it, let them know.
|
||||||
|
|
||||||
|
* If the ticket is a duplicate, reference the original ticket. Also
|
||||||
|
cross-reference the closed ticket by living a comment in the original one
|
||||||
|
-- this allows to access more related information about the reported bug
|
||||||
|
or requested feature.
|
||||||
|
|
||||||
|
* **Be polite.** No one likes having their ticket closed. It can be
|
||||||
|
frustrating or even discouraging. The best way to avoid turning people
|
||||||
|
off from contributing to Django is to be polite and friendly and to offer
|
||||||
|
suggestions for how they could improve this ticket and other tickets in
|
||||||
|
the future.
|
||||||
|
|
||||||
|
A ticket can be resolved in a number of ways:
|
||||||
|
|
||||||
|
* fixed
|
||||||
|
Used by the core developers once a patch has been rolled into
|
||||||
|
Django and the issue is fixed.
|
||||||
|
|
||||||
|
* invalid
|
||||||
|
Used if the ticket is found to be incorrect. This means that the
|
||||||
|
issue in the ticket is actually the result of a user error, or
|
||||||
|
describes a problem with something other than Django, or isn't
|
||||||
|
a bug report or feature request at all (for example, some new users
|
||||||
|
submit support queries as tickets).
|
||||||
|
|
||||||
|
* wontfix
|
||||||
|
Used when a core developer decides that this request is not
|
||||||
|
appropriate for consideration in Django. This is usually chosen after
|
||||||
|
discussion in the `django-developers`_ mailing list. Feel free to
|
||||||
|
start or join in discussions of "wontfix" tickets on the
|
||||||
|
django-developers_ mailing list, but please do not reopen tickets
|
||||||
|
closed as "wontfix" by core developers.
|
||||||
|
|
||||||
|
* duplicate
|
||||||
|
Used when another ticket covers the same issue. By closing duplicate
|
||||||
|
tickets, we keep all the discussion in one place, which helps
|
||||||
|
everyone.
|
||||||
|
|
||||||
|
* worksforme
|
||||||
|
Used when the ticket doesn't contain enough detail to replicate
|
||||||
|
the original bug.
|
||||||
|
|
||||||
|
* needsinfo
|
||||||
|
Used when the ticket does not contain enough information to replicate
|
||||||
|
the reported issue but is potentially still valid. The ticket
|
||||||
|
should be reopened when more information is supplied.
|
||||||
|
|
||||||
|
If you believe that the ticket was closed in error -- because you're
|
||||||
|
still having the issue, or it's popped up somewhere else, or the triagers have
|
||||||
|
made a mistake -- please reopen the ticket and provide further information.
|
||||||
|
Again, please do not reopen tickets that have been marked as "wontfix" by core
|
||||||
|
developers and bring the issue to django-developers_ instead.
|
||||||
|
|
||||||
|
.. _how-can-i-help-with-triaging:
|
||||||
|
|
||||||
|
How can I help with triaging?
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Although the core developers make the big decisions in the ticket triage
|
||||||
|
process, there's a lot that general community members can do to help the
|
||||||
|
triage process. Really, **ANYONE** can help.
|
||||||
|
|
||||||
|
Start by `creating an account on Trac`_. If you have an account but have
|
||||||
|
forgotten your password, you can reset it using the `password reset page`_.
|
||||||
|
|
||||||
|
Then, you can help out by:
|
||||||
|
|
||||||
|
* Closing "Unreviewed" tickets as "invalid", "worksforme" or "duplicate."
|
||||||
|
|
||||||
|
* Promoting "Unreviewed" tickets to "Design decision needed" if a design
|
||||||
|
decision needs to be made, or "Accepted" in case of obvious bugs or
|
||||||
|
sensible, clearly defined, feature requests.
|
||||||
|
|
||||||
|
* Correcting the "Needs tests", "Needs documentation", or "Has patch"
|
||||||
|
flags for tickets where they are incorrectly set.
|
||||||
|
|
||||||
|
* Setting the "`Easy pickings`_" flag for tickets that are small and
|
||||||
|
relatively straightforward.
|
||||||
|
|
||||||
|
* Checking that old tickets are still valid. If a ticket hasn't seen
|
||||||
|
any activity in a long time, it's possible that the problem has been
|
||||||
|
fixed but the ticket hasn't yet been closed.
|
||||||
|
|
||||||
|
* Contacting the owners of tickets that have been claimed but have not
|
||||||
|
seen any recent activity. If the owner doesn't respond after a week
|
||||||
|
or so, remove the owner's claim on the ticket.
|
||||||
|
|
||||||
|
* Identifying trends and themes in the tickets. If there a lot of bug
|
||||||
|
reports about a particular part of Django, it may indicate we should
|
||||||
|
consider refactoring that part of the code. If a trend is emerging,
|
||||||
|
you should raise it for discussion (referencing the relevant tickets)
|
||||||
|
on `django-developers`_.
|
||||||
|
|
||||||
|
* Set the *type* of tickets that are still uncategorized.
|
||||||
|
|
||||||
|
* Verify if patches submitted by other users are correct. If they do and
|
||||||
|
also contain appropriate documentation and tests then move them to the
|
||||||
|
"Ready for Checkin" stage. If they don't then leave a comment to explain
|
||||||
|
why and set the corresponding flags ("Patch needs improvement",
|
||||||
|
"Needs tests" etc.).
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The `Reports page`_ contains links to many useful Trac queries, including
|
||||||
|
several that are useful for triaging tickets and reviewing patches as
|
||||||
|
suggested above.
|
||||||
|
|
||||||
|
You can also find more :doc:`new-contributors`.
|
||||||
|
|
||||||
|
.. _Reports page: http://code.djangoproject.com/wiki/Reports
|
||||||
|
|
||||||
|
However, we do ask the following of all general community members working in
|
||||||
|
the ticket database:
|
||||||
|
|
||||||
|
* Please **don't** close tickets as "wontfix." The core developers will
|
||||||
|
make the final determination of the fate of a ticket, usually after
|
||||||
|
consultation with the community.
|
||||||
|
|
||||||
|
* Please **don't** promote your own tickets to "Ready for checkin". You
|
||||||
|
may mark other people's tickets which you've reviewed as "Ready for
|
||||||
|
checkin", but you should get at minimum one other community member to
|
||||||
|
review a patch that you submit.
|
||||||
|
|
||||||
|
* Please **don't** reverse a decision that has been made by a core
|
||||||
|
developer. If you disagree with a decision that has been made,
|
||||||
|
please post a message to `django-developers`_.
|
||||||
|
|
||||||
|
* If you're unsure if you should be making a change, don't make the
|
||||||
|
change but instead leave a comment with your concerns on the ticket,
|
||||||
|
or post a message to `django-developers`_. It's okay to be unsure,
|
||||||
|
but your input is still valuable.
|
||||||
|
|
||||||
|
.. _Trac: http://code.djangoproject.com/
|
||||||
|
.. _django-developers: http://groups.google.com/group/django-developers
|
||||||
|
.. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n
|
||||||
|
.. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases
|
||||||
|
.. _`easy pickings`: http://code.djangoproject.com/query?status=!closed&easy=1
|
||||||
|
.. _`creating an account on Trac`: http://www.djangoproject.com/accounts/register/
|
||||||
|
.. _password reset page: http://www.djangoproject.com/accounts/password/reset/
|
|
@ -0,0 +1,180 @@
|
||||||
|
=============
|
||||||
|
Branch policy
|
||||||
|
=============
|
||||||
|
|
||||||
|
In general, the trunk must be kept stable. People should be able to run
|
||||||
|
production sites against the trunk at any time. Additionally, commits to trunk
|
||||||
|
ought to be as atomic as possible -- smaller changes are better. Thus, large
|
||||||
|
feature changes -- that is, changes too large to be encapsulated in a single
|
||||||
|
patch, or changes that need multiple eyes on them -- must happen on dedicated
|
||||||
|
branches.
|
||||||
|
|
||||||
|
This means that if you want to work on a large feature -- anything that would
|
||||||
|
take more than a single patch, or requires large-scale refactoring -- you need
|
||||||
|
to do it on a feature branch. Our development process recognizes two options
|
||||||
|
for feature branches:
|
||||||
|
|
||||||
|
1. Feature branches using a distributed revision control system like
|
||||||
|
Git_, Mercurial_, Bazaar_, etc.
|
||||||
|
|
||||||
|
If you're familiar with one of these tools, this is probably your best
|
||||||
|
option since it doesn't require any support or buy-in from the Django
|
||||||
|
core developers.
|
||||||
|
|
||||||
|
However, do keep in mind that Django will continue to use Subversion
|
||||||
|
for the foreseeable future, and this will naturally limit the
|
||||||
|
recognition of your branch. Further, if your branch becomes eligible
|
||||||
|
for merging to trunk you'll need to find a core developer familiar
|
||||||
|
with your DVCS of choice who'll actually perform the merge.
|
||||||
|
|
||||||
|
If you do decided to start a distributed branch of Django and choose to
|
||||||
|
make it public, please add the branch to the `Django branches`_ wiki
|
||||||
|
page.
|
||||||
|
|
||||||
|
2. Feature branches using SVN have a higher bar. If you want a branch
|
||||||
|
in SVN itself, you'll need a "mentor" among the :doc:`core committers
|
||||||
|
</internals/committers>`. This person is responsible for actually
|
||||||
|
creating the branch, monitoring your process (see below), and
|
||||||
|
ultimately merging the branch into trunk.
|
||||||
|
|
||||||
|
If you want a feature branch in SVN, you'll need to ask in
|
||||||
|
`django-developers`_ for a mentor.
|
||||||
|
|
||||||
|
.. _git: http://git-scm.com/
|
||||||
|
.. _mercurial: http://mercurial.selenic.com/
|
||||||
|
.. _bazaar: http://bazaar.canonical.com/
|
||||||
|
.. _django branches: http://code.djangoproject.com/wiki/DjangoBranches
|
||||||
|
|
||||||
|
Branch rules
|
||||||
|
------------
|
||||||
|
|
||||||
|
We've got a few rules for branches born out of experience with what makes a
|
||||||
|
successful Django branch.
|
||||||
|
|
||||||
|
DVCS branches are obviously not under central control, so we have no way of
|
||||||
|
enforcing these rules. However, if you're using a DVCS, following these rules
|
||||||
|
will give you the best chance of having a successful branch (read: merged back
|
||||||
|
to trunk).
|
||||||
|
|
||||||
|
Developers with branches in SVN, however, **must** follow these rules. The
|
||||||
|
branch mentor will keep on eye on the branch and **will delete it** if these
|
||||||
|
rules are broken.
|
||||||
|
|
||||||
|
* Only branch entire copies of the Django tree, even if work is only
|
||||||
|
happening on part of that tree. This makes it painless to switch to a
|
||||||
|
branch.
|
||||||
|
|
||||||
|
* Merge changes from trunk no less than once a week, and preferably every
|
||||||
|
couple-three days.
|
||||||
|
|
||||||
|
In our experience, doing regular trunk merges is often the difference
|
||||||
|
between a successful branch and one that fizzles and dies.
|
||||||
|
|
||||||
|
If you're working on an SVN branch, you should be using `svnmerge.py`_
|
||||||
|
to track merges from trunk.
|
||||||
|
|
||||||
|
* Keep tests passing and documentation up-to-date. As with patches,
|
||||||
|
we'll only merge a branch that comes with tests and documentation.
|
||||||
|
|
||||||
|
.. _svnmerge.py: http://www.orcaware.com/svn/wiki/Svnmerge.py
|
||||||
|
|
||||||
|
Once the branch is stable and ready to be merged into the trunk, alert
|
||||||
|
`django-developers`_.
|
||||||
|
|
||||||
|
After a branch has been merged, it should be considered "dead"; write access
|
||||||
|
to it will be disabled, and old branches will be periodically "trimmed."
|
||||||
|
To keep our SVN wrangling to a minimum, we won't be merging from a given
|
||||||
|
branch into the trunk more than once.
|
||||||
|
|
||||||
|
Using branches
|
||||||
|
--------------
|
||||||
|
|
||||||
|
To use a branch, you'll need to do two things:
|
||||||
|
|
||||||
|
* Get the branch's code through Subversion.
|
||||||
|
|
||||||
|
* Point your Python ``site-packages`` directory at the branch's version of
|
||||||
|
the ``django`` package rather than the version you already have
|
||||||
|
installed.
|
||||||
|
|
||||||
|
Getting the code from Subversion
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
To get the latest version of a branch's code, check it out using Subversion:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
svn co http://code.djangoproject.com/svn/django/branches/<branch>/
|
||||||
|
|
||||||
|
...where ``<branch>`` is the branch's name. See the `list of branch names`_.
|
||||||
|
|
||||||
|
Alternatively, you can automatically convert an existing directory of the
|
||||||
|
Django source code as long as you've checked it out via Subversion. To do the
|
||||||
|
conversion, execute this command from within your ``django`` directory:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
svn switch http://code.djangoproject.com/svn/django/branches/<branch>/
|
||||||
|
|
||||||
|
The advantage of using ``svn switch`` instead of ``svn co`` is that the
|
||||||
|
``switch`` command retains any changes you might have made to your local copy
|
||||||
|
of the code. It attempts to merge those changes into the "switched" code. The
|
||||||
|
disadvantage is that it may cause conflicts with your local changes if the
|
||||||
|
"switched" code has altered the same lines of code.
|
||||||
|
|
||||||
|
(Note that if you use ``svn switch``, you don't need to point Python at the
|
||||||
|
new version, as explained in the next section.)
|
||||||
|
|
||||||
|
.. _list of branch names: http://code.djangoproject.com/browser/django/branches
|
||||||
|
|
||||||
|
.. _pointing-python-at-the-new-django-version:
|
||||||
|
|
||||||
|
Pointing Python at the new Django version
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Once you've retrieved the branch's code, you'll need to change your Python
|
||||||
|
``site-packages`` directory so that it points to the branch version of the
|
||||||
|
``django`` directory. (The ``site-packages`` directory is somewhere such as
|
||||||
|
``/usr/lib/python2.4/site-packages`` or
|
||||||
|
``/usr/local/lib/python2.4/site-packages`` or ``C:\Python\site-packages``.)
|
||||||
|
|
||||||
|
The simplest way to do this is by renaming the old ``django`` directory to
|
||||||
|
``django.OLD`` and moving the trunk version of the code into the directory
|
||||||
|
and calling it ``django``.
|
||||||
|
|
||||||
|
Alternatively, you can use a symlink called ``django`` that points to the
|
||||||
|
location of the branch's ``django`` package. If you want to switch back, just
|
||||||
|
change the symlink to point to the old code.
|
||||||
|
|
||||||
|
A third option is to use a `path file`_ (``<something>.pth``) which should
|
||||||
|
work on all systems (including Windows, which doesn't have symlinks
|
||||||
|
available). First, make sure there are no files, directories or symlinks named
|
||||||
|
``django`` in your ``site-packages`` directory. Then create a text file named
|
||||||
|
``django.pth`` and save it to your ``site-packages`` directory. That file
|
||||||
|
should contain a path to your copy of Django on a single line and optional
|
||||||
|
comments. Here is an example that points to multiple branches. Just uncomment
|
||||||
|
the line for the branch you want to use ('Trunk' in this example) and make
|
||||||
|
sure all other lines are commented::
|
||||||
|
|
||||||
|
# Trunk is a svn checkout of:
|
||||||
|
# http://code.djangoproject.com/svn/django/trunk/
|
||||||
|
#
|
||||||
|
/path/to/trunk
|
||||||
|
|
||||||
|
# <branch> is a svn checkout of:
|
||||||
|
# http://code.djangoproject.com/svn/django/branches/<branch>/
|
||||||
|
#
|
||||||
|
#/path/to/<branch>
|
||||||
|
|
||||||
|
# On windows a path may look like this:
|
||||||
|
# C:/path/to/<branch>
|
||||||
|
|
||||||
|
If you're using Django 0.95 or earlier and installed it using
|
||||||
|
``python setup.py install``, you'll have a directory called something like
|
||||||
|
``Django-0.95-py2.4.egg`` instead of ``django``. In this case, edit the file
|
||||||
|
``setuptools.pth`` and remove the line that references the Django ``.egg``
|
||||||
|
file. Then copy the branch's version of the ``django`` directory into
|
||||||
|
``site-packages``.
|
||||||
|
|
||||||
|
.. _path file: http://docs.python.org/library/site.html
|
||||||
|
.. _django-developers: http://groups.google.com/group/django-developers
|
|
@ -0,0 +1,190 @@
|
||||||
|
============
|
||||||
|
Coding Style
|
||||||
|
============
|
||||||
|
|
||||||
|
Please follow these coding standards when writing code for inclusion in Django.
|
||||||
|
|
||||||
|
Python style
|
||||||
|
------------
|
||||||
|
|
||||||
|
* Unless otherwise specified, follow :pep:`8`.
|
||||||
|
|
||||||
|
You could use a tool like `pep8.py`_ to check for some problems in this
|
||||||
|
area, but remember that PEP 8 is only a guide, so respect the style of
|
||||||
|
the surrounding code as a primary goal.
|
||||||
|
|
||||||
|
* Use four spaces for indentation.
|
||||||
|
|
||||||
|
* Use underscores, not camelCase, for variable, function and method names
|
||||||
|
(i.e. ``poll.get_unique_voters()``, not ``poll.getUniqueVoters``).
|
||||||
|
|
||||||
|
* Use ``InitialCaps`` for class names (or for factory functions that
|
||||||
|
return classes).
|
||||||
|
|
||||||
|
* In docstrings, use "action words" such as::
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
"""
|
||||||
|
Calculates something and returns the result.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
Here's an example of what not to do::
|
||||||
|
|
||||||
|
def foo():
|
||||||
|
"""
|
||||||
|
Calculate something and return the result.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
Template style
|
||||||
|
--------------
|
||||||
|
|
||||||
|
* In Django template code, put one (and only one) space between the curly
|
||||||
|
brackets and the tag contents.
|
||||||
|
|
||||||
|
Do this:
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{{ foo }}
|
||||||
|
|
||||||
|
Don't do this:
|
||||||
|
|
||||||
|
.. code-block:: html+django
|
||||||
|
|
||||||
|
{{foo}}
|
||||||
|
|
||||||
|
View style
|
||||||
|
----------
|
||||||
|
|
||||||
|
* In Django views, the first parameter in a view function should be called
|
||||||
|
``request``.
|
||||||
|
|
||||||
|
Do this::
|
||||||
|
|
||||||
|
def my_view(request, foo):
|
||||||
|
# ...
|
||||||
|
|
||||||
|
Don't do this::
|
||||||
|
|
||||||
|
def my_view(req, foo):
|
||||||
|
# ...
|
||||||
|
|
||||||
|
Model style
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Field names should be all lowercase, using underscores instead of
|
||||||
|
camelCase.
|
||||||
|
|
||||||
|
Do this::
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
first_name = models.CharField(max_length=20)
|
||||||
|
last_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
|
Don't do this::
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
FirstName = models.CharField(max_length=20)
|
||||||
|
Last_Name = models.CharField(max_length=40)
|
||||||
|
|
||||||
|
* The ``class Meta`` should appear *after* the fields are defined, with
|
||||||
|
a single blank line separating the fields and the class definition.
|
||||||
|
|
||||||
|
Do this::
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
first_name = models.CharField(max_length=20)
|
||||||
|
last_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name_plural = 'people'
|
||||||
|
|
||||||
|
Don't do this::
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
first_name = models.CharField(max_length=20)
|
||||||
|
last_name = models.CharField(max_length=40)
|
||||||
|
class Meta:
|
||||||
|
verbose_name_plural = 'people'
|
||||||
|
|
||||||
|
Don't do this, either::
|
||||||
|
|
||||||
|
class Person(models.Model):
|
||||||
|
class Meta:
|
||||||
|
verbose_name_plural = 'people'
|
||||||
|
|
||||||
|
first_name = models.CharField(max_length=20)
|
||||||
|
last_name = models.CharField(max_length=40)
|
||||||
|
|
||||||
|
* The order of model inner classes and standard methods should be as
|
||||||
|
follows (noting that these are not all required):
|
||||||
|
|
||||||
|
* All database fields
|
||||||
|
* Custom manager attributes
|
||||||
|
* ``class Meta``
|
||||||
|
* ``def __unicode__()``
|
||||||
|
* ``def __str__()``
|
||||||
|
* ``def save()``
|
||||||
|
* ``def get_absolute_url()``
|
||||||
|
* Any custom methods
|
||||||
|
|
||||||
|
* If ``choices`` is defined for a given model field, define the choices as
|
||||||
|
a tuple of tuples, with an all-uppercase name, either near the top of
|
||||||
|
the model module or just above the model class. Example::
|
||||||
|
|
||||||
|
GENDER_CHOICES = (
|
||||||
|
('M', 'Male'),
|
||||||
|
('F', 'Female'),
|
||||||
|
)
|
||||||
|
|
||||||
|
Use of ``django.conf.settings``
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Modules should not in general use settings stored in ``django.conf.settings``
|
||||||
|
at the top level (i.e. evaluated when the module is imported). The explanation
|
||||||
|
for this is as follows:
|
||||||
|
|
||||||
|
Manual configuration of settings (i.e. not relying on the
|
||||||
|
``DJANGO_SETTINGS_MODULE`` environment variable) is allowed and possible as
|
||||||
|
follows::
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
settings.configure({}, SOME_SETTING='foo')
|
||||||
|
|
||||||
|
However, if any setting is accessed before the ``settings.configure`` line,
|
||||||
|
this will not work. (Internally, ``settings`` is a ``LazyObject`` which
|
||||||
|
configures itself automatically when the settings are accessed if it has not
|
||||||
|
already been configured).
|
||||||
|
|
||||||
|
So, if there is a module containing some code as follows::
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.urlresolvers import get_callable
|
||||||
|
|
||||||
|
default_foo_view = get_callable(settings.FOO_VIEW)
|
||||||
|
|
||||||
|
...then importing this module will cause the settings object to be configured.
|
||||||
|
That means that the ability for third parties to import the module at the top
|
||||||
|
level is incompatible with the ability to configure the settings object
|
||||||
|
manually, or makes it very difficult in some circumstances.
|
||||||
|
|
||||||
|
Instead of the above code, a level of laziness or indirection must be used,
|
||||||
|
such as `django.utils.functional.LazyObject``, ``django.utils.functional.lazy``
|
||||||
|
or ``lambda``.
|
||||||
|
|
||||||
|
Miscellaneous
|
||||||
|
-------------
|
||||||
|
|
||||||
|
* Mark all strings for internationalization; see the :doc:`i18n
|
||||||
|
documentation </topics/i18n/index>` for details.
|
||||||
|
|
||||||
|
* Please don't put your name in the code you contribute. Our policy is to
|
||||||
|
keep contributors' names in the ``AUTHORS`` file distributed with Django
|
||||||
|
-- not scattered throughout the codebase itself. Feel free to include a
|
||||||
|
change to the ``AUTHORS`` file in your patch if you make more than a
|
||||||
|
single trivial change.
|
||||||
|
|
||||||
|
.. _pep8.py: http://pypi.python.org/pypi/pep8/
|
|
@ -0,0 +1,15 @@
|
||||||
|
============
|
||||||
|
Writing code
|
||||||
|
============
|
||||||
|
|
||||||
|
So you'd like to write some code to improve Django. Awesome! Browse the
|
||||||
|
following sections to find out how to give your code patches the best
|
||||||
|
chances to be included in Django core:
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
coding-style
|
||||||
|
unit-tests
|
||||||
|
submitting-patches
|
||||||
|
branch-policy
|
|
@ -0,0 +1,160 @@
|
||||||
|
==================
|
||||||
|
Submitting patches
|
||||||
|
==================
|
||||||
|
|
||||||
|
We're always grateful for patches to Django's code. Indeed, bug reports
|
||||||
|
with associated patches will get fixed *far* more quickly than those
|
||||||
|
without patches.
|
||||||
|
|
||||||
|
"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:
|
||||||
|
|
||||||
|
* `Create an account`_ to use 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 "Assigned to" section of the ticket.
|
||||||
|
If it's assigned to "nobody," then it's available to be claimed.
|
||||||
|
Otherwise, somebody else is working on this ticket, and you either find
|
||||||
|
another bug/feature to work on, or contact the developer working on the
|
||||||
|
ticket to offer your help.
|
||||||
|
|
||||||
|
* Log into your account, if you haven't already, by clicking "Login" in
|
||||||
|
the upper right of the ticket page.
|
||||||
|
|
||||||
|
* Claim the ticket by clicking the radio button next to "Accept ticket"
|
||||||
|
near the bottom of the page, then clicking "Submit changes."
|
||||||
|
|
||||||
|
.. _Create an account: https://www.djangoproject.com/accounts/register/
|
||||||
|
.. _password reset page: https://www.djangoproject.com/accounts/password/reset/
|
||||||
|
|
||||||
|
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?
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Of course, 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. Just submit your patch and be done with
|
||||||
|
it.
|
||||||
|
|
||||||
|
.. _patch-style:
|
||||||
|
|
||||||
|
Patch style
|
||||||
|
-----------
|
||||||
|
|
||||||
|
* Make sure your code matches our :doc:`coding-style`.
|
||||||
|
|
||||||
|
* Submit patches in the format returned by the ``svn diff`` command.
|
||||||
|
An exception is for code changes that are described more clearly in
|
||||||
|
plain English than in code. Indentation is the most common example; it's
|
||||||
|
hard to read patches when the only difference in code is that it's
|
||||||
|
indented.
|
||||||
|
|
||||||
|
Patches in ``git diff`` format are also acceptable.
|
||||||
|
|
||||||
|
* When creating patches, always run ``svn diff`` from the top-level
|
||||||
|
``trunk`` directory -- i.e., the one that contains ``django``, ``docs``,
|
||||||
|
``tests``, ``AUTHORS``, etc. This makes it easy for other people to
|
||||||
|
apply your patches.
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
* Check the "Has patch" box on the ticket details. This will make it
|
||||||
|
obvious that the ticket includes a patch, and it will add the ticket to
|
||||||
|
the `list of tickets with patches`_.
|
||||||
|
|
||||||
|
* The code required to fix a problem or add a feature is an essential part
|
||||||
|
of a patch, but it is not the only part. A good patch should also
|
||||||
|
include a regression test to validate the behavior that has been fixed
|
||||||
|
(and prevent the problem from arising again).
|
||||||
|
|
||||||
|
* If the code associated with a patch adds a new feature, or modifies
|
||||||
|
behavior of an existing feature, the patch should also contain
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
Non-trivial patches
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
A "non-trivial" patch is one that is more than a simple bug fix. It's a patch
|
||||||
|
that introduces Django functionality and makes some sort of design decision.
|
||||||
|
|
||||||
|
If you provide a non-trivial patch, include evidence that alternatives have
|
||||||
|
been discussed on `django-developers`_. If you're not sure whether your patch
|
||||||
|
should be considered non-trivial, just ask.
|
||||||
|
|
||||||
|
Javascript patches
|
||||||
|
------------------
|
||||||
|
|
||||||
|
.. versionadded:: 1.2
|
||||||
|
|
||||||
|
Django's admin system leverages the jQuery framework to increase the
|
||||||
|
capabilities of the admin interface. In conjunction, there is an emphasis on
|
||||||
|
admin javascript performance and minimizing overall admin media file size.
|
||||||
|
Serving compressed or "minified" versions of javascript files is considered
|
||||||
|
best practice in this regard.
|
||||||
|
|
||||||
|
To that end, patches for javascript files should include both the original
|
||||||
|
code for future development (e.g. "foo.js"), and a compressed version for
|
||||||
|
production use (e.g. "foo.min.js"). Any links to the file in the codebase
|
||||||
|
should point to the compressed version.
|
||||||
|
|
||||||
|
To simplify the process of providing optimized javascript code, Django
|
||||||
|
includes a handy script which should be used to create a "minified" version.
|
||||||
|
This script is located at ``/contrib/admin/media/js/compress.py``.
|
||||||
|
|
||||||
|
Behind the scenes, ``compress.py`` is a front-end for Google's
|
||||||
|
`Closure Compiler`_ which is written in Java. However, the Closure Compiler
|
||||||
|
library is not bundled with Django directly, so those wishing to contribute
|
||||||
|
complete javascript patches will need to download and install the library
|
||||||
|
independently.
|
||||||
|
|
||||||
|
The Closure Compiler library requires Java version 6 or higher (Java 1.6 or
|
||||||
|
higher on Mac OS X). Note that Mac OS X 10.5 and earlier did not ship with
|
||||||
|
Java 1.6 by default, so it may be necessary to upgrade your Java installation
|
||||||
|
before the tool will be functional. Also note that even after upgrading Java,
|
||||||
|
the default `/usr/bin/java` command may remain linked to the previous Java
|
||||||
|
binary, so relinking that command may be necessary as well.
|
||||||
|
|
||||||
|
Please don't forget to run ``compress.py`` and include the ``diff`` of the
|
||||||
|
minified scripts when submitting patches for Django's javascript.
|
||||||
|
|
||||||
|
.. _Closure Compiler: http://code.google.com/closure/compiler/
|
||||||
|
.. _django-developers: http://groups.google.com/group/django-developers
|
||||||
|
.. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority
|
||||||
|
.. _ticket tracker: http://code.djangoproject.com/newticket
|
|
@ -0,0 +1,167 @@
|
||||||
|
==========
|
||||||
|
Unit tests
|
||||||
|
==========
|
||||||
|
|
||||||
|
Django comes with a test suite of its own, in the ``tests`` directory of the
|
||||||
|
Django tarball. It's our policy to make sure all tests pass at all times.
|
||||||
|
|
||||||
|
The tests cover:
|
||||||
|
|
||||||
|
* Models and the database API (``tests/modeltests/``).
|
||||||
|
* Everything else in core Django code (``tests/regressiontests``)
|
||||||
|
* Contrib apps (``django/contrib/<contribapp>/tests``, see below)
|
||||||
|
|
||||||
|
We appreciate any and all contributions to the test suite!
|
||||||
|
|
||||||
|
The Django tests all use the testing infrastructure that ships with Django for
|
||||||
|
testing applications. See :doc:`Testing Django applications </topics/testing>`
|
||||||
|
for an explanation of how to write new tests.
|
||||||
|
|
||||||
|
.. _running-unit-tests:
|
||||||
|
|
||||||
|
Running the unit tests
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Quickstart
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
Running the tests requires a Django settings module that defines the
|
||||||
|
databases to use. To make it easy to get started. Django provides a
|
||||||
|
sample settings module that uses the SQLite database. To run the tests
|
||||||
|
with this sample ``settings`` module, ``cd`` into the Django
|
||||||
|
``tests/`` directory and run:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./runtests.py --settings=test_sqlite
|
||||||
|
|
||||||
|
If you get an ``ImportError: No module named django.contrib`` error,
|
||||||
|
you need to add your install of Django to your ``PYTHONPATH``. For
|
||||||
|
more details on how to do this, read
|
||||||
|
:ref:`pointing-python-at-the-new-django-version`.
|
||||||
|
|
||||||
|
Using another ``settings`` module
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The included settings module allows you to run the test suite using
|
||||||
|
SQLite. If you want to test behavior using a different database (and
|
||||||
|
if you're proposing patches for Django, it's a good idea to test
|
||||||
|
across databases), you may need to define your own settings file.
|
||||||
|
|
||||||
|
To run the tests with different settings, ``cd`` to the ``tests/`` directory
|
||||||
|
and type:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./runtests.py --settings=path.to.django.settings
|
||||||
|
|
||||||
|
The :setting:`DATABASES` setting in this test settings module needs to define
|
||||||
|
two databases:
|
||||||
|
|
||||||
|
* A ``default`` database. This database should use the backend that
|
||||||
|
you want to use for primary testing
|
||||||
|
|
||||||
|
* A database with the alias ``other``. The ``other`` database is
|
||||||
|
used to establish that queries can be directed to different
|
||||||
|
databases. As a result, this database can use any backend you
|
||||||
|
want. It doesn't need to use the same backend as the ``default``
|
||||||
|
database (although it can use the same backend if you want to).
|
||||||
|
|
||||||
|
If you're using a backend that isn't SQLite, you will need to provide other
|
||||||
|
details for each database:
|
||||||
|
|
||||||
|
* The :setting:`USER` option for each of your databases needs to
|
||||||
|
specify an existing user account for the database.
|
||||||
|
|
||||||
|
* The :setting:`PASSWORD` option needs to provide the password for
|
||||||
|
the :setting:`USER` that has been specified.
|
||||||
|
|
||||||
|
* The :setting:`NAME` option must be the name of an existing database to
|
||||||
|
which the given user has permission to connect. The unit tests will not
|
||||||
|
touch this database; the test runner creates a new database whose name
|
||||||
|
is :setting:`NAME` prefixed with ``test_``, and this test database is
|
||||||
|
deleted when the tests are finished. This means your user account needs
|
||||||
|
permission to execute ``CREATE DATABASE``.
|
||||||
|
|
||||||
|
You will also need to ensure that your database uses UTF-8 as the default
|
||||||
|
character set. If your database server doesn't use UTF-8 as a default charset,
|
||||||
|
you will need to include a value for ``TEST_CHARSET`` in the settings
|
||||||
|
dictionary for the applicable database.
|
||||||
|
|
||||||
|
Running only some of the tests
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Django's entire test suite takes a while to run, and running every single test
|
||||||
|
could be redundant if, say, you just added a test to Django that you want to
|
||||||
|
run quickly without running everything else. You can run a subset of the unit
|
||||||
|
tests by appending the names of the test modules to ``runtests.py`` on the
|
||||||
|
command line.
|
||||||
|
|
||||||
|
For example, if you'd like to run tests only for generic relations and
|
||||||
|
internationalization, type:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./runtests.py --settings=path.to.settings generic_relations i18n
|
||||||
|
|
||||||
|
How do you find out the names of individual tests? Look in
|
||||||
|
``tests/modeltests`` and ``tests/regressiontests`` -- each directory name
|
||||||
|
there is the name of a test.
|
||||||
|
|
||||||
|
If you just want to run a particular class of tests, you can specify a list of
|
||||||
|
paths to individual test classes. For example, to run the ``TranslationTests``
|
||||||
|
of the ``i18n`` module, type:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./runtests.py --settings=path.to.settings i18n.TranslationTests
|
||||||
|
|
||||||
|
Going beyond that, you can specify an individual test method like this:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
./runtests.py --settings=path.to.settings i18n.TranslationTests.test_lazy_objects
|
||||||
|
|
||||||
|
Running all the tests
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
If you want to run the full suite of tests, you'll need to install a number of
|
||||||
|
dependencies:
|
||||||
|
|
||||||
|
* PyYAML_
|
||||||
|
* Markdown_
|
||||||
|
* Textile_
|
||||||
|
* Docutils_
|
||||||
|
* setuptools_
|
||||||
|
* memcached_, plus a :ref:`supported Python binding <memcached>`
|
||||||
|
* gettext_ (:ref:`gettext_on_windows`)
|
||||||
|
|
||||||
|
If you want to test the memcached cache backend, you'll also need to define
|
||||||
|
a :setting:`CACHES` setting that points at your memcached instance.
|
||||||
|
|
||||||
|
Each of these dependencies is optional. If you're missing any of them, the
|
||||||
|
associated tests will be skipped.
|
||||||
|
|
||||||
|
.. _PyYAML: http://pyyaml.org/wiki/PyYAML
|
||||||
|
.. _Markdown: http://pypi.python.org/pypi/Markdown/1.7
|
||||||
|
.. _Textile: http://pypi.python.org/pypi/textile
|
||||||
|
.. _docutils: http://pypi.python.org/pypi/docutils/0.4
|
||||||
|
.. _setuptools: http://pypi.python.org/pypi/setuptools/
|
||||||
|
.. _memcached: http://www.danga.com/memcached/
|
||||||
|
.. _gettext: http://www.gnu.org/software/gettext/manual/gettext.html
|
||||||
|
|
||||||
|
Contrib apps
|
||||||
|
------------
|
||||||
|
|
||||||
|
Tests for apps in ``django/contrib/`` go in their respective directories under
|
||||||
|
``django/contrib/``, in a ``tests.py`` file. (You can split the tests over
|
||||||
|
multiple modules by using a ``tests`` directory in the normal Python way.)
|
||||||
|
|
||||||
|
For the tests to be found, a ``models.py`` file must exist (it doesn't
|
||||||
|
have to have anything in it). If you have URLs that need to be
|
||||||
|
mapped, put them in ``tests/urls.py``.
|
||||||
|
|
||||||
|
To run tests for just one contrib app (e.g. ``markup``), use the same
|
||||||
|
method as above::
|
||||||
|
|
||||||
|
./runtests.py --settings=settings markup
|
|
@ -1,10 +1,28 @@
|
||||||
How the Django documentation works
|
=====================
|
||||||
==================================
|
Writing documentation
|
||||||
|
=====================
|
||||||
|
|
||||||
\... and how to contribute.
|
We place a high importance on consistency and readability of documentation.
|
||||||
|
After all, Django was created in a journalism environment! So we treat our
|
||||||
|
documentation like we treat our code: we aim to improve it as often as
|
||||||
|
possible.
|
||||||
|
|
||||||
Django's documentation uses the Sphinx__ documentation system, which in turn is
|
Documentation changes generally come in two forms:
|
||||||
based on docutils__. The basic idea is that lightly-formatted plain-text
|
|
||||||
|
* General improvements -- Typo corrections, error fixes and better
|
||||||
|
explanations through clearer writing and more examples.
|
||||||
|
|
||||||
|
* New features -- Documentation of features that have been added to the
|
||||||
|
framework since the last release.
|
||||||
|
|
||||||
|
This section explains how writers can craft their documentation changes
|
||||||
|
in the most useful and least error-prone ways.
|
||||||
|
|
||||||
|
Getting started with Sphinx
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Django's documentation uses the Sphinx__ documentation system, which in turn
|
||||||
|
is based on docutils__. The basic idea is that lightly-formatted plain-text
|
||||||
documentation is transformed into HTML, PDF, and any other output format.
|
documentation is transformed into HTML, PDF, and any other output format.
|
||||||
|
|
||||||
__ http://sphinx.pocoo.org/
|
__ http://sphinx.pocoo.org/
|
||||||
|
@ -22,7 +40,8 @@ Sphinx -- ``easy_install Sphinx`` should do the trick.
|
||||||
|
|
||||||
__ http://pygments.org
|
__ http://pygments.org
|
||||||
|
|
||||||
Then, building the HTML is easy; just ``make html`` from the ``docs`` directory.
|
Then, building the HTML is easy; just ``make html`` from the ``docs``
|
||||||
|
directory.
|
||||||
|
|
||||||
To get started contributing, you'll want to read the `reStructuredText
|
To get started contributing, you'll want to read the `reStructuredText
|
||||||
Primer`__. After that, you'll want to read about the `Sphinx-specific markup`__
|
Primer`__. After that, you'll want to read about the `Sphinx-specific markup`__
|
||||||
|
@ -31,8 +50,62 @@ that's used to manage metadata, indexing, and cross-references.
|
||||||
__ http://sphinx.pocoo.org/rest.html
|
__ http://sphinx.pocoo.org/rest.html
|
||||||
__ http://sphinx.pocoo.org/markup/
|
__ http://sphinx.pocoo.org/markup/
|
||||||
|
|
||||||
The main thing to keep in mind as you write and edit docs is that the more
|
Commonly used terms
|
||||||
semantic markup you can add the better. So::
|
-------------------
|
||||||
|
|
||||||
|
Here are some style guidelines on commonly used terms throughout the
|
||||||
|
documentation:
|
||||||
|
|
||||||
|
* **Django** -- when referring to the framework, capitalize Django. It is
|
||||||
|
lowercase only in Python code and in the djangoproject.com logo.
|
||||||
|
|
||||||
|
* **email** -- no hyphen.
|
||||||
|
|
||||||
|
* **MySQL**
|
||||||
|
|
||||||
|
* **PostgreSQL**
|
||||||
|
|
||||||
|
* **Python** -- when referring to the language, capitalize Python.
|
||||||
|
|
||||||
|
* **realize**, **customize**, **initialize**, etc. -- use the American
|
||||||
|
"ize" suffix, not "ise."
|
||||||
|
|
||||||
|
* **SQLite**
|
||||||
|
|
||||||
|
* **subclass** -- it's a single word without a hyphen, both as a verb
|
||||||
|
("subclass that model") and as a noun ("create a subclass").
|
||||||
|
|
||||||
|
* **Web**, **World Wide Web**, **the Web** -- note Web is always
|
||||||
|
capitalized when referring to the World Wide Web.
|
||||||
|
|
||||||
|
* **Web site** -- use two words, with Web capitalized.
|
||||||
|
|
||||||
|
Django-specific terminology
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
* **model** -- it's not capitalized.
|
||||||
|
|
||||||
|
* **template** -- it's not capitalized.
|
||||||
|
|
||||||
|
* **URLconf** -- use three capitalized letters, with no space before
|
||||||
|
"conf."
|
||||||
|
|
||||||
|
* **view** -- it's not capitalized.
|
||||||
|
|
||||||
|
Guidelines for reStructuredText files
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
These guidelines regulate the format of our reST (reStructuredText)
|
||||||
|
documentation:
|
||||||
|
|
||||||
|
* In section titles, capitalize only initial words and proper nouns.
|
||||||
|
|
||||||
|
* Wrap the documentation at 80 characters wide, unless a code example
|
||||||
|
is significantly less readable when split over two lines, or for another
|
||||||
|
good reason.
|
||||||
|
|
||||||
|
* The main thing to keep in mind as you write and edit docs is that the
|
||||||
|
more semantic markup you can add the better. So::
|
||||||
|
|
||||||
Add ``django.contrib.auth`` to your ``INSTALLED_APPS``...
|
Add ``django.contrib.auth`` to your ``INSTALLED_APPS``...
|
||||||
|
|
||||||
|
@ -40,14 +113,15 @@ Isn't nearly as helpful as::
|
||||||
|
|
||||||
Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...
|
Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...
|
||||||
|
|
||||||
This is because Sphinx will generate proper links for the latter, which greatly
|
This is because Sphinx will generate proper links for the latter, which
|
||||||
helps readers. There's basically no limit to the amount of useful markup you can
|
greatly helps readers. There's basically no limit to the amount of
|
||||||
add.
|
useful markup you can add.
|
||||||
|
|
||||||
Django-specific markup
|
Django-specific markup
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Besides the `Sphinx built-in markup`__, Django's docs defines some extra description units:
|
Besides the `Sphinx built-in markup`__, Django's docs defines some extra
|
||||||
|
description units:
|
||||||
|
|
||||||
__ http://sphinx.pocoo.org/markup/desc.html
|
__ http://sphinx.pocoo.org/markup/desc.html
|
||||||
|
|
||||||
|
@ -87,6 +161,26 @@ __ http://sphinx.pocoo.org/markup/desc.html
|
||||||
|
|
||||||
To link, use ``:djadminopt:`--traceback```.
|
To link, use ``:djadminopt:`--traceback```.
|
||||||
|
|
||||||
|
.. _documenting-new-features:
|
||||||
|
|
||||||
|
Documenting new features
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Our policy for new features is:
|
||||||
|
|
||||||
|
**All documentation of new features should be written in a way that
|
||||||
|
clearly designates the features are only available in the Django
|
||||||
|
development version. Assume documentation readers are using the latest
|
||||||
|
release, not the development version.**
|
||||||
|
|
||||||
|
Our preferred way for marking new features is by prefacing the features'
|
||||||
|
documentation with: "``.. versionadded:: X.Y``", followed by an optional one
|
||||||
|
line comment and a mandatory blank line.
|
||||||
|
|
||||||
|
General improvements, or other changes to the APIs that should be emphasized
|
||||||
|
should use the "``.. versionchanged:: X.Y``" directive (with the same format
|
||||||
|
as the ``versionadded`` mentioned above.
|
||||||
|
|
||||||
An example
|
An example
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
@ -127,7 +221,8 @@ example:
|
||||||
<available-settings>`. For a list of deprecated settings see
|
<available-settings>`. For a list of deprecated settings see
|
||||||
:ref:`deprecated-settings`.
|
:ref:`deprecated-settings`.
|
||||||
|
|
||||||
You can find both in the :doc:`settings reference document </ref/settings>`.
|
You can find both in the :doc:`settings reference document
|
||||||
|
</ref/settings>`.
|
||||||
|
|
||||||
We use the Sphinx doc_ cross reference element when we want to link to
|
We use the Sphinx doc_ cross reference element when we want to link to
|
||||||
another document as a whole and the ref_ element when we want to link to
|
another document as a whole and the ref_ element when we want to link to
|
||||||
|
@ -147,31 +242,34 @@ example:
|
||||||
|
|
||||||
Default: ``()`` (Empty tuple)
|
Default: ``()`` (Empty tuple)
|
||||||
|
|
||||||
Used for admin-site settings modules, this should be a tuple of settings
|
Used for admin-site settings modules, this should be a tuple of
|
||||||
modules (in the format ``'foo.bar.baz'``) for which this site is an
|
settings modules (in the format ``'foo.bar.baz'``) for which this site
|
||||||
admin.
|
is an admin.
|
||||||
|
|
||||||
The admin site uses this in its automatically-introspected
|
The admin site uses this in its automatically-introspected
|
||||||
documentation of models, views and template tags.
|
documentation of models, views and template tags.
|
||||||
|
|
||||||
This marks up the following header as the "canonical" target for the
|
This marks up the following header as the "canonical" target for the
|
||||||
setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``, I
|
setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``,
|
||||||
can reference it using ``:setting:`ADMIN_FOR```.
|
I can reference it using ``:setting:`ADMIN_FOR```.
|
||||||
|
|
||||||
That's basically how everything fits together.
|
That's basically how everything fits together.
|
||||||
|
|
||||||
TODO
|
.. _improving-the-documentation:
|
||||||
----
|
|
||||||
|
|
||||||
The work is mostly done, but here's what's left, in rough order of priority.
|
Improving the documentation
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
A few small improvements can be made to make the documentation read and
|
||||||
|
look better:
|
||||||
|
|
||||||
* Most of the various ``index.txt`` documents have *very* short or even
|
* Most of the various ``index.txt`` documents have *very* short or even
|
||||||
non-existent intro text. Each of those documents needs a good short intro
|
non-existent intro text. Each of those documents needs a good short
|
||||||
the content below that point.
|
intro the content below that point.
|
||||||
|
|
||||||
* The glossary is very perfunctory. It needs to be filled out.
|
* The glossary is very perfunctory. It needs to be filled out.
|
||||||
|
|
||||||
* Add more metadata targets: there's lots of places that look like::
|
* Add more metadata targets. Lots of places look like::
|
||||||
|
|
||||||
``File.close()``
|
``File.close()``
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
|
@ -194,28 +292,24 @@ The work is mostly done, but here's what's left, in rough order of priority.
|
||||||
|
|
||||||
__ http://sphinx.pocoo.org/markup/desc.html#info-field-lists
|
__ http://sphinx.pocoo.org/markup/desc.html#info-field-lists
|
||||||
|
|
||||||
|
* Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead
|
||||||
|
of ````ADMIN_FOR````.
|
||||||
|
|
||||||
|
* Use directives where appropriate. Some directives
|
||||||
|
(e.g. ``.. setting::``) are prefix-style directives; they go *before*
|
||||||
|
the unit they're describing. These are known as "crossref" directives.
|
||||||
|
Others (e.g. ``.. class::``) generate their own markup; these should go
|
||||||
|
inside the section they're describing. These are called
|
||||||
|
"description units".
|
||||||
|
|
||||||
|
You can tell which are which by looking at in
|
||||||
|
:file:`_ext/djangodocs.py`; it registers roles as one of the other.
|
||||||
|
|
||||||
* Add ``.. code-block:: <lang>`` to literal blocks so that they get
|
* Add ``.. code-block:: <lang>`` to literal blocks so that they get
|
||||||
highlighted.
|
highlighted.
|
||||||
|
|
||||||
Hints
|
* When referring to classes/functions/modules, etc., you'll want to use
|
||||||
-----
|
the fully-qualified name of the target
|
||||||
|
|
||||||
Some hints for making things look/read better:
|
|
||||||
|
|
||||||
* Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead of
|
|
||||||
````ADMIN_FOR````.
|
|
||||||
|
|
||||||
* Some directives (``.. setting::``, for one) are prefix-style directives;
|
|
||||||
they go *before* the unit they're describing. These are known as
|
|
||||||
"crossref" directives. Others (``.. class::``, e.g.) generate their own
|
|
||||||
markup; these should go inside the section they're describing. These are
|
|
||||||
called "description units".
|
|
||||||
|
|
||||||
You can tell which are which by looking at in :file:`_ext/djangodocs.py`;
|
|
||||||
it registers roles as one of the other.
|
|
||||||
|
|
||||||
* When referring to classes/functions/modules, etc., you'll want to use the
|
|
||||||
fully-qualified name of the target
|
|
||||||
(``:class:`django.contrib.contenttypes.models.ContentType```).
|
(``:class:`django.contrib.contenttypes.models.ContentType```).
|
||||||
|
|
||||||
Since this doesn't look all that awesome in the output -- it shows the
|
Since this doesn't look all that awesome in the output -- it shows the
|
|
@ -14,10 +14,9 @@ the hood".
|
||||||
these internals if we must.
|
these internals if we must.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 2
|
||||||
|
|
||||||
contributing
|
contributing/index
|
||||||
documentation
|
|
||||||
committers
|
committers
|
||||||
release-process
|
release-process
|
||||||
deprecation
|
deprecation
|
||||||
|
|
Loading…
Reference in New Issue