mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	git-svn-id: http://code.djangoproject.com/svn/django/branches/queryset-refactor@7281 bcc190cf-cafb-0310-a4f2-bffc1f526a37
		
			
				
	
	
		
			943 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			943 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| ======================
 | |
| 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 many ways you can help Django's development:
 | |
| 
 | |
|     * Blog about Django.  We syndicate all the Django blogs we know about on
 | |
|       the `community page`_; contact jacob@jacobian.org if you've got a blog
 | |
|       you'd like to see on that page.
 | |
| 
 | |
|     * Report bugs and request features in our `ticket tracker`_.  Please read
 | |
|       `Reporting bugs`_, below, for the details on how we like our bug reports
 | |
|       served up.
 | |
| 
 | |
|     * Submit patches for new and/or fixed behavior.  Please read `Submitting
 | |
|       patches`_, below, for details on how to submit a patch.
 | |
| 
 | |
|     * Join the `django-developers`_ mailing list and share your ideas for how
 | |
|       to improve Django.  We're always open to suggestions, although we're
 | |
|       likely to be skeptical of large-scale suggestions without some code to
 | |
|       back it up.
 | |
| 
 | |
|     * Triage patches that have been submitted by other users. Please read
 | |
|       `Ticket triage`_ below, for details on the triage process.
 | |
| 
 | |
| That's all you need to know if you'd like to join the Django development
 | |
| community. The rest of this document describes the details of how our community
 | |
| works and how it handles bugs, mailing lists, and all the other minutiae of
 | |
| Django development.
 | |
| 
 | |
| 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 FAQ_ to see if your issue might be a well-known question.
 | |
| 
 | |
|     * **Do** `search the tracker`_ to see if your issue has already been filed.
 | |
| 
 | |
|     * **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** use the ticket system to ask support questions.  Use the
 | |
|       `django-users`_ list, or the `#django`_ IRC channel for that.
 | |
| 
 | |
|     * **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.
 | |
| 
 | |
|     * **Don't** reopen issues that have been marked "wontfix". 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`_.
 | |
| 
 | |
|     * **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 triagers, so we
 | |
|       see them as they are filed.
 | |
| 
 | |
| .. _django-updates: http://groups.google.com/group/django-updates
 | |
| 
 | |
| Reporting security issues
 | |
| =========================
 | |
| 
 | |
| Report security issues 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.
 | |
| 
 | |
|     * Halt all other development as long as is needed to develop a fix, including
 | |
|       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 everyone we know to be running the affected version(s) of
 | |
|       Django. We will send these notifications through private e-mail 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.
 | |
| 
 | |
| 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 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: http://www.djangoproject.com/accounts/register/
 | |
| 
 | |
| 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!
 | |
| 
 | |
| Core Django developers go through the list of claimed tickets from time to
 | |
| time, checking whether any progress has been made. If there's no sign of
 | |
| progress on a particular claimed ticket for a week or two after it's been
 | |
| claimed, we will unclaim it for you 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. That way, we'll know
 | |
| not to unclaim it. 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
 | |
| -----------
 | |
| 
 | |
|     * Make sure your code matches our `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.
 | |
| 
 | |
| 	* 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.
 | |
| 
 | |
| Ticket triage
 | |
| =============
 | |
| 
 | |
| Unfortunately, not all bug reports in the `ticket tracker`_ provide all
 | |
| the `required details`_. A number of tickets have patches, but those patches
 | |
| don't meet all the requirements of a `good patch`_.
 | |
| 
 | |
| One way to help out is to *triage* bugs that have been reported by other
 | |
| users. A couple of dedicated volunteers work on this regularly, but more help
 | |
| is always appreciated.
 | |
| 
 | |
| Most of the workflow is based around the concept of a ticket's "triage stage".
 | |
| This stage describes where in its lifetime a given ticket is at any time.
 | |
| Along with a handful of flags, this field easily tells us what and who each
 | |
| ticket is waiting on.
 | |
| 
 | |
| Since a picture is worth a thousand words, let's start there:
 | |
| 
 | |
| .. image:: http://media.djangoproject.com/img/doc/djangotickets.png
 | |
|    :height: 451
 | |
|    :width: 590
 | |
|    :alt: Django's ticket workflow
 | |
| 
 | |
| We've got two roles here:
 | |
| 
 | |
|     * Core developers: people with commit access who make the decisions and
 | |
|       write the bulk of the code.
 | |
| 
 | |
|     * Ticket triagers: community members who keep track of tickets, making
 | |
|       sure the tickets are always categorized correctly.
 | |
| 
 | |
| Second, note the five triage stages:
 | |
| 
 | |
|     1. A ticket starts as "Unreviewed", meaning that a triager has yet to
 | |
|        examine the ticket and move it along.
 | |
| 
 | |
|     2. "Design decision needed" means "this concept requires a design
 | |
|        decision," which should be discussed either in the ticket comments or on
 | |
|        django-developers.
 | |
| 
 | |
|     3. Once a ticket is ruled to be approved for fixing, it's moved into the
 | |
|        "Accepted" stage. This stage is where all the real work gets done.
 | |
| 
 | |
|     4. In some cases, a ticket might get moved to the "Someday/Maybe" state.
 | |
|        This means the ticket is an enhancement request that we might consider
 | |
|        adding to the framework if an excellent patch is submitted. These
 | |
|        tickets are not a high priority.
 | |
| 
 | |
|     5. If a ticket has an associated patch (see below), a triager will review
 | |
|        the patch. If the patch is complete, it'll be marked as "ready for
 | |
|        checkin" so that a core developer knows to review and check in the
 | |
|        patches.
 | |
| 
 | |
| The second part of this workflow involves a set of flags the describe what the
 | |
| ticket has or needs in order to be "ready for checkin":
 | |
| 
 | |
|     "Has patch"
 | |
|         This means the ticket has an associated patch_. 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 a fix 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, or that the code doesn't live up to our standards.
 | |
| 
 | |
| A ticket can be resolved in a number of ways:
 | |
| 
 | |
|     "fixed"
 | |
|         Used by one of 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 or a user error.
 | |
| 
 | |
|     "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, and you should
 | |
|         feel free to join in when it's something you care about.
 | |
| 
 | |
|     "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 triage team is unable to replicate the original bug.
 | |
| 
 | |
| 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 tell us why. Please do not
 | |
| reopen tickets that have been marked as "wontfix" by core developers.
 | |
| 
 | |
| .. _required details: `Reporting bugs`_
 | |
| .. _good patch: `Patch style`_
 | |
| .. _patch: `Submitting patches`_
 | |
| 
 | |
| Submitting and maintaining translations
 | |
| =======================================
 | |
| 
 | |
| Various parts of Django, such as the admin site and validator error messages,
 | |
| are internationalized. This means they display different text depending on a
 | |
| user's language setting.
 | |
| 
 | |
| These translations are contributed by Django users worldwide. If you find an
 | |
| incorrect translation, or if you'd like to add a language that isn't yet
 | |
| translated, here's what to do:
 | |
| 
 | |
|     * Join the `Django i18n mailing list`_ and introduce yourself.
 | |
|     * Create translations using the methods described in the
 | |
|       `i18n documentation`_.
 | |
|     * Create a diff of the ``.po`` file against the current Subversion trunk.
 | |
|     * Make sure that `` bin/compile-messages.py -l <lang>`` runs without
 | |
|       producing any warnings.
 | |
|     * Attach the patch to a ticket in Django's ticket system.
 | |
| 
 | |
| .. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
 | |
| .. _i18n documentation: ../i18n/
 | |
| 
 | |
| Coding style
 | |
| ============
 | |
| 
 | |
| Please follow these coding standards when writing code for inclusion in Django:
 | |
| 
 | |
|     * 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).
 | |
| 
 | |
|     * Mark all strings for internationalization; see the `i18n documentation`_
 | |
|       for details.
 | |
| 
 | |
|     * 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
 | |
| 
 | |
|     * 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.
 | |
| 
 | |
| Template style
 | |
| --------------
 | |
| 
 | |
|     * In Django template code, put one (and only one) space between the curly
 | |
|       brackets and the tag contents.
 | |
| 
 | |
|       Do this::
 | |
| 
 | |
|           {{ foo }}
 | |
| 
 | |
|       Don't do this::
 | |
| 
 | |
|           {{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
 | |
|         * ``class Meta``
 | |
|         * ``class Admin``
 | |
|         * ``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'),
 | |
|           )
 | |
| 
 | |
| Documentation style
 | |
| ===================
 | |
| 
 | |
| We place a high importance on consistency and readability of documentation.
 | |
| (After all, Django was created in a journalism environment!)
 | |
| 
 | |
| How to document new features
 | |
| ----------------------------
 | |
| 
 | |
| We treat our documentation like we treat our code: we aim to improve it as
 | |
| often as possible. This section explains how writers can craft their
 | |
| documentation changes in the most useful and least error-prone ways.
 | |
| 
 | |
| Documentation changes 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.
 | |
| 
 | |
| Our philosophy is that "general improvements" are something that *all* current
 | |
| Django users should benefit from, including users of trunk *and* users of the
 | |
| latest release. Hence, the documentation section on djangoproject.com points
 | |
| people by default to the newest versions of the docs, because they have the
 | |
| latest and greatest content. (In fact, the Web site pulls directly from the
 | |
| Subversion repository, converting to HTML on the fly.)
 | |
| 
 | |
| But this decision to feature bleeding-edge documentation has one large caveat:
 | |
| any documentation of *new* features will be seen by Django users who don't
 | |
| necessarily have access to those features yet, because they're only using the
 | |
| latest release. Thus, our policy 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 traditional way of marking new features is by prefacing the features'
 | |
| documentation with: "New in Django development version." Changes aren't
 | |
| *required* to include this exact text, but all documentation of new features
 | |
| should include the phrase "development version," so we can find and remove
 | |
| those phrases for the next release.
 | |
| 
 | |
| Guidelines for ReST files
 | |
| -------------------------
 | |
| 
 | |
| These guidelines regulate the format of our ReST 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.
 | |
| 
 | |
| 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.
 | |
| 
 | |
|     * **e-mail** -- it has a 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.
 | |
| 
 | |
| Committing code
 | |
| ===============
 | |
| 
 | |
| 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.
 | |
| 
 | |
|     * 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 -- Added 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.
 | |
| 
 | |
| 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/``).
 | |
|     * The cache system (``tests/regressiontests/cache.py``).
 | |
|     * The ``django.utils.dateformat`` module (``tests/regressiontests/dateformat/``).
 | |
|     * Database typecasts (``tests/regressiontests/db_typecasts/``).
 | |
|     * The template system (``tests/regressiontests/templates/`` and
 | |
|       ``tests/regressiontests/defaultfilters/``).
 | |
|     * ``QueryDict`` objects (``tests/regressiontests/httpwrappers/``).
 | |
|     * Markup template tags (``tests/regressiontests/markup/``).
 | |
| 
 | |
| 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 `Testing Django applications`_ for an explanation of
 | |
| how to write new tests.
 | |
| 
 | |
| .. _Testing Django applications: ../testing/
 | |
| 
 | |
| Running the unit tests
 | |
| ----------------------
 | |
| 
 | |
| To run the tests, ``cd`` to the ``tests/`` directory and type::
 | |
| 
 | |
|     ./runtests.py --settings=path.to.django.settings
 | |
| 
 | |
| Yes, the unit tests need a settings module, but only for database connection
 | |
| info, with the ``DATABASE_ENGINE`` setting. You'll also need a ``ROOT_URLCONF``
 | |
| setting (its value is ignored; it just needs to be present).
 | |
| 
 | |
| If you're using the ``sqlite3`` database backend, no further settings are
 | |
| needed. A temporary database will be created in memory when running the tests.
 | |
| 
 | |
| If you're using another backend:
 | |
| 
 | |
|     * Your ``DATABASE_USER`` setting needs to specify an existing user account
 | |
|       for the database engine.
 | |
| 
 | |
|     * The ``DATABASE_NAME`` setting 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
 | |
|       ``DATABASE_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``.
 | |
| 
 | |
| To run a subset of the unit tests, append the names of the test modules to the
 | |
| ``runtests.py`` command line. See the list of directories in
 | |
| ``tests/modeltests`` and ``tests/regressiontests`` for module names.
 | |
| 
 | |
| As an example, if Django is not in your ``PYTHONPATH``, you placed
 | |
| ``settings.py`` in the ``tests/`` directory, and you'd like to only run tests
 | |
| for generic relations and internationalization, type::
 | |
| 
 | |
|     PYTHONPATH=..
 | |
|     ./runtests.py --settings=settings generic_relations i18n
 | |
| 
 | |
| 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 most effectively make a request:
 | |
| 
 | |
|     * 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.
 | |
| 
 | |
| 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 below.
 | |
| 
 | |
| Branch policy
 | |
| =============
 | |
| 
 | |
| In general, most development is confined to the trunk, and the trunk
 | |
| is kept stable. People should be able to run production sites against the
 | |
| trunk at any time.
 | |
| 
 | |
| Thus, large architectural changes -- that is, changes too large to be
 | |
| encapsulated in a single patch, or changes that need multiple eyes on them --
 | |
| will have dedicated branches. See, for example, the `i18n branch`_. If you
 | |
| have a change of this nature that you'd like to work on, ask on
 | |
| `django-developers`_ for a branch to be created for you. We'll create a branch
 | |
| for pretty much any kind of experimenting you'd like to do.
 | |
| 
 | |
| We will 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.
 | |
| 
 | |
| Developers working on a branch should periodically merge changes from the trunk
 | |
| into the branch. Please merge at least once a week. Every time you merge from
 | |
| the trunk, note the merge and revision numbers in the commit message.
 | |
| 
 | |
| 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::
 | |
| 
 | |
|     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::
 | |
| 
 | |
|     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
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| 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/lib/module-site.html
 | |
| 
 | |
| Official releases
 | |
| =================
 | |
| 
 | |
| Django's release numbering works as follows:
 | |
| 
 | |
|     * Versions are numbered in the form ``A.B`` or ``A.B.C``.
 | |
| 
 | |
|     * ``A`` is the major version number, which is only incremented for major
 | |
|       changes to Django, and these changes are not necessarily
 | |
|       backwards-compatible. That is, code you wrote for Django 6.0 may break
 | |
|       when we release Django 7.0.
 | |
| 
 | |
|     * ``B`` is the minor version number, which is incremented for large yet
 | |
|       backwards compatible changes.  Code written for Django 6.4 will continue
 | |
|       to work under Django 6.5.
 | |
| 
 | |
|       A minor release may deprecate certain features in previous releases. If a
 | |
|       feature in version ``A.B`` is deprecated, it will continue to work in
 | |
|       version ``A.B+1``. In version ``A.B+2``, use of the feature will raise a
 | |
|       ``PendingDeprecationWarning`` but will continue to work.  Version
 | |
|       ``A.B+3`` will remove the feature entirely. Major point releases will
 | |
|       always remove deprecated features immediately.
 | |
| 
 | |
|     * ``C`` is the micro version number which, is incremented for bug and
 | |
|       security fixes.  A new micro-release will always be 100%
 | |
|       backwards-compatible with the previous micro-release.
 | |
| 
 | |
|     * In some cases, we'll make release candidate releases. These are of the
 | |
|       form ``A.BrcN``, which means the ``Nth`` candidate release of version
 | |
|       ``A.B``.
 | |
| 
 | |
| An exception to this version numbering scheme is the pre-1.0 Django code.
 | |
| There's no guarantee of backwards-compatibility until the 1.0 release.
 | |
| 
 | |
| In Subversion, each Django release will be tagged under `tags/releases`_.  If
 | |
| it's necessary to release a bug fix release or a security release that doesn't
 | |
| come from the trunk, we'll copy that tag to ``branches/releases`` to make the
 | |
| bug fix release.
 | |
| 
 | |
| Deciding on features
 | |
| ====================
 | |
| 
 | |
| Once a feature's been requested and discussed, eventually we'll have a decision
 | |
| about whether to include the feature or drop it.
 | |
| 
 | |
| 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.  Tough decisions will be discussed by
 | |
| all full committers and finally decided by the Benevolent Dictators for Life,
 | |
| Adrian and Jacob.
 | |
| 
 | |
| Commit access
 | |
| =============
 | |
| 
 | |
| Django has two types of committers:
 | |
| 
 | |
| Full 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 very high for full commit access. It will only be granted by
 | |
|     unanimous approval of all existing full committers, and the decision will err
 | |
|     on the side of rejection.
 | |
| 
 | |
| 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.
 | |
| 
 | |
|     Like full committers, partial commit access is by unanimous approval of all
 | |
|     full committers (and any other partial committers in the same area).
 | |
|     However, the bar is set lower; proven expertise in the area in question is
 | |
|     likely to be sufficient.
 | |
| 
 | |
| To request commit access, please contact an existing committer privately. Public
 | |
| requests for commit access are potential flame-war starters, and will be ignored.
 | |
| 
 | |
| .. _community page: http://www.djangoproject.com/community/
 | |
| .. _ticket tracker: http://code.djangoproject.com/newticket
 | |
| .. _django-developers: http://groups.google.com/group/django-developers
 | |
| .. _FAQ: http://www.djangoproject.com/documentation/faq/
 | |
| .. _search the tracker: http://code.djangoproject.com/search
 | |
| .. _django-users: http://groups.google.com/group/django-users
 | |
| .. _`#django`: irc://irc.freenode.net/django
 | |
| .. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority
 | |
| .. _PEP 8: http://www.python.org/peps/pep-0008.html
 | |
| .. _pep8.py: http://svn.browsershots.org/trunk/devtools/pep8/pep8.py
 | |
| .. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n
 | |
| .. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases
 |