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:
Jannis Leidel 2011-05-27 10:49:47 +00:00
parent 69cfee2f16
commit 407f62fd31
18 changed files with 1806 additions and 1750 deletions

View File

@ -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.

View File

@ -11,7 +11,6 @@ you quickly accomplish common tasks.
apache-auth
auth-remote-user
contribute
custom-management-commands
custom-model-fields
custom-template-tags

View File

@ -200,7 +200,7 @@ The Django open-source project
==============================
* **Community:**
:doc:`How to get involved <internals/contributing>` |
:doc:`How to get involved <internals/contributing/index>` |
:doc:`The release process <internals/release-process>` |
:doc:`Team of committers <internals/committers>` |
:doc:`The Django source code repository <internals/svn>`
@ -209,7 +209,7 @@ The Django open-source project
:doc:`Overview <misc/design-philosophies>`
* **Documentation:**
:doc:`About this documentation <internals/documentation>`
:doc:`About this documentation <internals/contributing/writing-documentation>`
* **Third-party distributions:**
:doc:`Overview <misc/distributions>`

View File

@ -58,6 +58,8 @@ Current developers
Currently, Django is led by a team of volunteers from around the globe.
.. _django-bdfls:
BDFLs
-----

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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/

View File

@ -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

View File

@ -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/

View File

@ -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/

View File

@ -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

View File

@ -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/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
based on docutils__. The basic idea is that lightly-formatted plain-text
Documentation changes generally come in two forms:
* 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.
__ http://sphinx.pocoo.org/
@ -22,7 +40,8 @@ Sphinx -- ``easy_install Sphinx`` should do the trick.
__ 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
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/markup/
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::
Commonly used terms
-------------------
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``...
@ -40,14 +113,15 @@ Isn't nearly as helpful as::
Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...
This is because Sphinx will generate proper links for the latter, which greatly
helps readers. There's basically no limit to the amount of useful markup you can
add.
This is because Sphinx will generate proper links for the latter, which
greatly helps readers. There's basically no limit to the amount of
useful markup you can add.
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
@ -87,6 +161,26 @@ __ http://sphinx.pocoo.org/markup/desc.html
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
----------
@ -127,7 +221,8 @@ example:
<available-settings>`. For a list of deprecated settings see
: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
another document as a whole and the ref_ element when we want to link to
@ -147,31 +242,34 @@ example:
Default: ``()`` (Empty tuple)
Used for admin-site settings modules, this should be a tuple of settings
modules (in the format ``'foo.bar.baz'``) for which this site is an
admin.
Used for admin-site settings modules, this should be a tuple of
settings modules (in the format ``'foo.bar.baz'``) for which this site
is an admin.
The admin site uses this in its automatically-introspected
documentation of models, views and template tags.
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
can reference it using ``:setting:`ADMIN_FOR```.
setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``,
I can reference it using ``:setting:`ADMIN_FOR```.
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
non-existent intro text. Each of those documents needs a good short intro
the content below that point.
non-existent intro text. Each of those documents needs a good short
intro the content below that point.
* 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()``
~~~~~~~~~~~~~~~~
@ -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
* 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
highlighted.
Hints
-----
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
* 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```).
Since this doesn't look all that awesome in the output -- it shows the

View File

@ -14,10 +14,9 @@ the hood".
these internals if we must.
.. toctree::
:maxdepth: 1
:maxdepth: 2
contributing
documentation
contributing/index
committers
release-process
deprecation