diff options
| author | Joseph Kocherhans <joseph@jkocherhans.com> | 2007-09-15 22:25:52 +0000 |
|---|---|---|
| committer | Joseph Kocherhans <joseph@jkocherhans.com> | 2007-09-15 22:25:52 +0000 |
| commit | 019e3c61e4390b0e5ad981256d6426e24083626a (patch) | |
| tree | 5efefabcad63dbe68f0c2b53c4ff5100667fc24d /docs | |
| parent | b2669113821eeb8b3cd654bbf5ab33053894b923 (diff) | |
newforms-admin: Merged to [6332].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6342 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/add_ons.txt | 5 | ||||
| -rw-r--r-- | docs/apache_auth.txt | 45 | ||||
| -rw-r--r-- | docs/authentication.txt | 29 | ||||
| -rw-r--r-- | docs/cache.txt | 9 | ||||
| -rw-r--r-- | docs/contenttypes.txt | 258 | ||||
| -rw-r--r-- | docs/contributing.txt | 84 | ||||
| -rw-r--r-- | docs/databases.txt | 2 | ||||
| -rw-r--r-- | docs/databrowse.txt | 25 | ||||
| -rw-r--r-- | docs/db-api.txt | 25 | ||||
| -rw-r--r-- | docs/django-admin.txt | 30 | ||||
| -rw-r--r-- | docs/fastcgi.txt | 5 | ||||
| -rw-r--r-- | docs/form_preview.txt | 97 | ||||
| -rw-r--r-- | docs/generic_views.txt | 44 | ||||
| -rw-r--r-- | docs/i18n.txt | 142 | ||||
| -rw-r--r-- | docs/install.txt | 76 | ||||
| -rw-r--r-- | docs/model-api.txt | 22 | ||||
| -rw-r--r-- | docs/modpython.txt | 2 | ||||
| -rw-r--r-- | docs/newforms.txt | 59 | ||||
| -rw-r--r-- | docs/request_response.txt | 15 | ||||
| -rw-r--r-- | docs/settings.txt | 35 | ||||
| -rw-r--r-- | docs/shortcuts.txt | 143 | ||||
| -rw-r--r-- | docs/sites.txt | 28 | ||||
| -rw-r--r-- | docs/templates.txt | 40 | ||||
| -rw-r--r-- | docs/templates_python.txt | 68 | ||||
| -rw-r--r-- | docs/testing.txt | 22 | ||||
| -rw-r--r-- | docs/tutorial01.txt | 10 |
26 files changed, 1149 insertions, 171 deletions
diff --git a/docs/add_ons.txt b/docs/add_ons.txt index a1d78b8685..00c6e0dcf4 100644 --- a/docs/add_ons.txt +++ b/docs/add_ons.txt @@ -70,8 +70,9 @@ An abstraction of the following workflow: "Display an HTML form, force a preview, then do something with the submission." -Full documentation for this feature does not yet exist, but you can read the -code and docstrings in ``django/contrib/formtools/preview.py`` for a start. +See the `form preview documentation`_. + +.. _form preview documentation: ../form_preview/ humanize ======== diff --git a/docs/apache_auth.txt b/docs/apache_auth.txt index 583cb96b39..9beb1ba43a 100644 --- a/docs/apache_auth.txt +++ b/docs/apache_auth.txt @@ -21,14 +21,57 @@ file, you'll need to use mod_python's ``PythonAuthenHandler`` directive along with the standard ``Auth*`` and ``Require`` directives:: <Location /example/> - AuthType basic + AuthType Basic AuthName "example.com" Require valid-user SetEnv DJANGO_SETTINGS_MODULE mysite.settings PythonAuthenHandler django.contrib.auth.handlers.modpython </Location> + +.. admonition:: Using the authentication handler with Apache 2.2 + If you're using Apache 2.2, you'll need to take a couple extra steps. + + You'll need to ensure that ``mod_auth_basic`` and ``mod_authz_user`` + are loaded. These might be compiled staticly into Apache, or you might + need to use ``LoadModule`` to load them dynamically (as shown in the + example at the bottom of this note). + + You'll also need to insert configuration directives that prevent Apache + from trying to use other authentication modules. Depnding on which other + authentication modules you have loaded, you might need one or more of + the following directives:: + + AuthBasicAuthoritative Off + AuthDefaultAuthoritative Off + AuthzLDAPAuthoritative Off + AuthzDBMAuthoritative Off + AuthzDefaultAuthoritative Off + AuthzGroupFileAuthoritative Off + AuthzOwnerAuthoritative Off + AuthzUserAuthoritative Off + + A complete configuration, with differences between Apache 2.0 and + Apache 2.2 marked in bold, would look something like: + + .. parsed-literal:: + + **LoadModule auth_basic_module modules/mod_auth_basic.so** + **LoadModule authz_user_module modules/mod_authz_user.so** + + ... + + <Location /exmaple/> + AuthType Basic + AuthName "example.com" + **AuthBasicAuthoritative Off** + Require valid-user + + SetEnv DJANGO_SETTINGS_MODULE mysite.settings + PythonAuthenHandler django.contrib.auth.handlers.modpython + </Location> + By default, the authentication handler will limit access to the ``/example/`` location to users marked as staff members. You can use a set of ``PythonOption`` directives to modify this behavior: diff --git a/docs/authentication.txt b/docs/authentication.txt index 131a8930b5..713e86c140 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -244,6 +244,9 @@ Anonymous users the ``django.contrib.auth.models.User`` interface, with these differences: * ``id`` is always ``None``. + * ``is_staff`` and ``is_superuser`` are always False. + * ``is_active`` is always True. + * ``groups`` and ``user_permissions`` are always empty. * ``is_anonymous()`` returns ``True`` instead of ``False``. * ``is_authenticated()`` returns ``False`` instead of ``True``. * ``has_perm()`` always returns ``False``. @@ -402,11 +405,29 @@ introduced in Python 2.4:: def my_view(request): # ... +In the Django development version, ``login_required`` also takes an optional +``redirect_field_name`` parameter. Example:: + + from django.contrib.auth.decorators import login_required + + def my_view(request): + # ... + my_view = login_required(redirect_field_name='redirect_to')(my_view) + +Again, an equivalent example of the more compact decorator syntax introduced in Python 2.4:: + + from django.contrib.auth.decorators import login_required + + @login_required(redirect_field_name='redirect_to') + def my_view(request): + # ... + ``login_required`` does the following: * If the user isn't logged in, redirect to ``settings.LOGIN_URL`` (``/accounts/login/`` by default), passing the current absolute URL - in the query string as ``next``. For example: + in the query string as ``next`` or the value of ``redirect_field_name``. + For example: ``/accounts/login/?next=/polls/3/``. * If the user is logged in, execute the view normally. The view code is free to assume the user is logged in. @@ -974,10 +995,10 @@ Writing an authentication backend --------------------------------- An authentication backend is a class that implements two methods: -``get_user(id)`` and ``authenticate(**credentials)``. +``get_user(user_id)`` and ``authenticate(**credentials)``. -The ``get_user`` method takes an ``id`` -- which could be a username, database -ID or whatever -- and returns a ``User`` object. +The ``get_user`` method takes a ``user_id`` -- which could be a username, +database ID or whatever -- and returns a ``User`` object. The ``authenticate`` method takes credentials as keyword arguments. Most of the time, it'll just look like this:: diff --git a/docs/cache.txt b/docs/cache.txt index 92b5c1b43d..8ba0383909 100644 --- a/docs/cache.txt +++ b/docs/cache.txt @@ -524,6 +524,15 @@ the value of the ``CACHE_MIDDLEWARE_SETTINGS`` setting. If you use a custom ``max_age`` in a ``cache_control`` decorator, the decorator will take precedence, and the header values will be merged correctly.) +If you want to use headers to disable caching altogether, +``django.views.decorators.never_cache`` is a view decorator that adds +headers to ensure the response won't be cached by browsers or other caches. Example:: + + from django.views.decorators.cache import never_cache + @never_cache + def myview(request): + ... + .. _`Cache-Control spec`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 Other optimizations diff --git a/docs/contenttypes.txt b/docs/contenttypes.txt new file mode 100644 index 0000000000..3ef83f2066 --- /dev/null +++ b/docs/contenttypes.txt @@ -0,0 +1,258 @@ +========================== +The contenttypes framework +========================== + +Django includes a "contenttypes" application that can track all of +the models installed in your Django-powered project, providing a +high-level, generic interface for working with your models. + +Overview +======== + +At the heart of the contenttypes application is the ``ContentType`` +model, which lives at +``django.contrib.contenttypes.models.ContentType``. Instances of +``ContentType`` represent and store information about the models +installed in your project, and new instances of ``ContentType`` are +automatically created whenever new models are installed. + +Instances of ``ContentType`` have methods for returning the model +classes they represent and for querying objects from those models. +``ContentType`` also has a `custom manager`_ that adds methods for +working with ``ContentType`` and for obtaining instances of +``ContentType`` for a particular model. + +Relations between your models and ``ContentType`` can also be used to +enable "generic" relationships between an instance of one of your +models and instances of any model you have installed. + +.. _custom manager: ../model-api/#custom-managers + +Installing the contenttypes framework +===================================== + +The contenttypes framework is included in the default +``INSTALLED_APPS`` list created by ``django-admin.py startproject``, +but if you've removed it or if you manually set up your +``INSTALLED_APPS`` list, you can enable it by adding +``'django.contrib.contenttypes'`` to your ``INSTALLED_APPS`` setting. + +It's generally a good idea to have the contenttypes framework +installed; several of Django's other bundled applications require it: + + * The admin application uses it to log the history of each object + added or changed through the admin interface. + + * Django's `authentication framework`_ uses it to tie user permissions + to specific models. + + * Django's comments system (``django.contrib.comments``) uses it to + "attach" comments to any installed model. + +.. _authentication framework: ../authentication/ + +The ``ContentType`` model +========================= + +Each instance of ``ContentType`` has three fields which, taken +together, uniquely describe an installed model: + + ``app_label`` + The name of the application the model is part of. This is taken from + the ``app_label`` attribute of the model, and includes only the *last* + part of the application's Python import path; + "django.contrib.contenttypes", for example, becomes an ``app_label`` + of "contenttypes". + + ``model`` + The name of the model class. + + ``name`` + The human-readable name of the model. This is taken from + `the verbose_name attribute`_ of the model. + +Let's look at an example to see how this works. If you already have +the contenttypes application installed, and then add `the sites +application`_ to your ``INSTALLED_APPS`` setting and run ``manage.py +syncdb`` to install it, the model ``django.contrib.sites.models.Site`` +will be installed into your database. Along with it a new instance +of ``ContentType`` will be created with the following values: + + * ``app_label`` will be set to ``'sites'`` (the last part of the Python + path "django.contrib.sites"). + + * ``model`` will be set to ``'site'``. + + * ``name`` will be set to ``'site'``. + +.. _the verbose_name attribute: ../model-api/#verbose_name +.. _the sites application: ../sites/ + +Methods on ``ContentType`` instances +==================================== + +Each ``ContentType`` instance has methods that allow you to get from a +``ContentType`` instance to the model it represents, or to retrieve objects +from that model: + + ``get_object_for_this_type(**kwargs)`` + Takes a set of valid `lookup arguments`_ for the model the + ``ContentType`` represents, and does `a get() lookup`_ on that + model, returning the corresponding object. + + ``model_class()`` + Returns the model class represented by this ``ContentType`` + instance. + +For example, we could look up the ``ContentType`` for the ``User`` model:: + + >>> from django.contrib.contenttypes.models import ContentType + >>> user_type = ContentType.objects.get(app_label="auth", model="user") + >>> user_type + <ContentType: user> + +And then use it to query for a particular ``User``, or to get access +to the ``User`` model class:: + + >>> user_type.model_class() + <class 'django.contrib.auth.models.User'> + >>> user_type.get_object_for_this_type(username='Guido') + <User: Guido> + +Together, ``get_object_for_this_type`` and ``model_class`` enable two +extremely important use cases: + + 1. Using these methods, you can write high-level generic code that + performs queries on any installed model -- instead of importing and + using a single specific model class, you can pass an ``app_label`` + and ``model`` into a ``ContentType`` lookup at runtime, and then + work with the model class or retrieve objects from it. + + 2. You can relate another model to ``ContentType`` as a way of tying + instances of it to particular model classes, and use these methods + to get access to those model classes. + +Several of Django's bundled applications make use of the latter +technique. For example, `the permissions system`_ in Django's +authentication framework uses a ``Permission`` model with a foreign +key to ``ContentType``; this lets ``Permission`` represent concepts +like "can add blog entry" or "can delete news story". + +.. _lookup arguments: ../db-api/#field-lookups +.. _a get() lookup: ../db-api/#get-kwargs +.. _the permissions system: ../authentication/#permissions + +The ``ContentTypeManager`` +-------------------------- + +``ContentType`` also has a custom manager, ``ContentTypeManager``, +which adds the following methods: + + ``clear_cache()`` + Clears an internal cache used by ``ContentType`` to keep track of which + models for which it has created ``ContentType`` instances. You probably + won't ever need to call this method yourself; Django will call it + automatically when it's needed. + + ``get_for_model(model)`` + Takes either a model class or an instance of a model, and returns the + ``ContentType`` instance representing that model. + +The ``get_for_model`` method is especially useful when you know you +need to work with a ``ContentType`` but don't want to go to the +trouble of obtaining the model's metadata to perform a manual lookup:: + + >>> from django.contrib.auth.models import User + >>> user_type = ContentType.objects.get_for_model(User) + >>> user_type + <ContentType: user> + +Generic relations +================= + +Adding a foreign key from one of your own models to ``ContentType`` +allows your model to effectively tie itself to another model class, as +in the example of the ``Permission`` model above. But it's possible to +go one step further and use ``ContentType`` to enable truly generic +(sometimes called "polymorphic") relationships between models. + +A simple example is a tagging system, which might look like this:: + + from django.db import models + from django.contrib.contenttypes.models import ContentType + from django.contrib.contenttypes import generic + + class TaggedItem(models.Model): + tag = models.SlugField() + content_type = models.ForeignKey(ContentType) + object_id = models.PositiveIntegerField() + content_object = generic.GenericForeignKey('content_type', 'object_id') + + def __unicode__(self): + return self.tag + +A normal ``ForeignKey`` can only "point to" one other model, which +means that if the ``TaggedItem`` model used a ``ForeignKey`` it would have to +choose one and only one model to store tags for. The contenttypes +application provides a special field type -- +``django.contrib.contenttypes.generic.GenericForeignKey`` -- which +works around this and allows the relationship to be with any +model. There are three parts to setting up a ``GenericForeignKey``: + + 1. Give your model a ``ForeignKey`` to ``ContentType``. + + 2. Give your model a field that can store a primary-key value from the + models you'll be relating to. (For most models, this means an + ``IntegerField`` or ``PositiveIntegerField``.) + + 3. Give your model a ``GenericForeignKey``, and pass it the names of + the two fields described above. If these fields are named + "content_type" and "object_id", you can omit this -- those are the + default field names ``GenericForeignKey`` will look for. + +This will enable an API similar to the one used for a normal ``ForeignKey``; +each ``TaggedItem`` will have a ``content_object`` field that returns the +object it's related to, and you can also assign to that field or use it when +creating a ``TaggedItem``:: + + >>> from django.contrib.models.auth import User + >>> guido = User.objects.get(username='Guido') + >>> t = TaggedItem(content_object=guido, tag='bdfl') + >>> t.save() + >>> t.content_object + <User: Guido> + +Reverse generic relations +------------------------- + +If you know which models you'll be using most often, you can also add +a "reverse" generic relationship to enable an additional API. For example:: + + class Bookmark(models.Model): + url = models.URLField() + tags = generic.GenericRelation(TaggedItem) + +``Bookmark`` instances will each have a ``tags`` attribute, which can +be used to retrieve their associated ``TaggedItems``:: + + >>> b = Bookmark('http://www.djangoproject.com/') + >>> b.save() + >>> t1 = TaggedItem(content_object=b, tag='django') + >>> t1.save() + >>> t2 = TaggedItem(content_object=b, tag='python') + >>> t2.save() + >>> b.tags.all() + [<TaggedItem: django>, <TaggedItem: python>] + +If you don't add the reverse relationship, you can do the lookup manually:: + + >>> b = Bookmark.objects.get(url='http://www.djangoproject.com/) + >>> bookmark_type = ContentType.objects.get_for_model(b) + >>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id, + ... object_id=b.id) + [<TaggedItem: django>, <TaggedItem: python>] + +Note that if you delete an object that has a ``GenericRelation``, any objects +which have a ``GenericForeignKey`` pointing at it will be deleted as well. In +the example above, this means that if a ``Bookmark`` object were deleted, any +``TaggedItem`` objects pointing at it would be deleted at the same time. diff --git a/docs/contributing.txt b/docs/contributing.txt index 4ec5c3c2af..3200a87012 100644 --- a/docs/contributing.txt +++ b/docs/contributing.txt @@ -112,6 +112,61 @@ 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 ----------- @@ -599,10 +654,31 @@ info, with the ``DATABASE_ENGINE`` setting. You will also need a ``ROOT_URLCONF` setting (its value is ignored; it just needs to be present) and a ``SITE_ID`` setting (any non-zero integer value will do) in order for all the tests to pass. -The unit tests will not touch your existing databases; they create a new -database, called ``django_test_db``, which is deleted when the tests are -finished. This means your user account needs permission to execute ``CREATE -DATABASE``. +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 =================== diff --git a/docs/databases.txt b/docs/databases.txt index ed0cb61bc3..21ff4c7434 100644 --- a/docs/databases.txt +++ b/docs/databases.txt @@ -117,7 +117,7 @@ Here's a sample configuration which uses a MySQL option file:: [client] database = DATABASE_NAME user = DATABASE_USER - passwd = DATABASE_PASSWORD + password = DATABASE_PASSWORD default-character-set = utf8 Several other MySQLdb connection options may be useful, such as ``ssl``, diff --git a/docs/databrowse.txt b/docs/databrowse.txt index 81e9e8e83b..72e1c71720 100644 --- a/docs/databrowse.txt +++ b/docs/databrowse.txt @@ -58,4 +58,29 @@ How to use Databrowse 4. Run the Django server and visit ``/databrowse/`` in your browser. +Requiring user login +==================== + +You can restrict access to logged-in users with only a few extra lines of +code. Simply add the following import to your URLconf:: + + from django.contrib.auth.decorators import login_required + +Then modify the URLconf so that the ``databrowse.site.root`` view is decorated +with ``login_required``:: + + (r'^databrowse/(.*)', login_required(databrowse.site.root)), + +If you haven't already added support for user logins to your URLconf, as +described in the `user authentication docs`_, then you will need to do so +now with the following mapping:: + + (r'^accounts/login/$', 'django.contrib.auth.views.login'), + +The final step is to create the login form required by +``django.contrib.auth.views.login``. The `user authentication docs`_ +provide full details and a sample template that can be used for this +purpose. + .. _template loader docs: ../templates_python/#loader-types +.. _user authentication docs: ../authentication/ diff --git a/docs/db-api.txt b/docs/db-api.txt index 2a90b2d171..08b5391e3c 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -481,7 +481,7 @@ In SQL terms, that evaluates to:: WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello') This example excludes all entries whose ``pub_date`` is later than 2005-1-3 -AND whose headline is NOT "Hello":: +OR whose headline is "Hello":: Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello') @@ -511,6 +511,9 @@ like so:: Entry.objects.order_by('?') +Note: ``order_by('?')`` queries may be expensive and slow, depending on the +database backend you're using. + To order by a field in a different table, add the other table's name and a dot, like so:: @@ -799,6 +802,9 @@ of the arguments is required, but you should use at least one of them. Entry.objects.extra(where=['headline=%s'], params=['Lennon']) + The combined number of placeholders in the list of strings for ``select`` + or ``where`` should equal the number of values in the ``params`` list. + QuerySet methods that do not return QuerySets --------------------------------------------- @@ -945,6 +951,23 @@ Example:: If you pass ``in_bulk()`` an empty list, you'll get an empty dictionary. +``iterator()`` +~~~~~~~~~~~~ + +Evaluates the ``QuerySet`` (by performing the query) and returns an +`iterator`_ over the results. A ``QuerySet`` typically reads all of +its results and instantiates all of the corresponding objects the +first time you access it; ``iterator()`` will instead read results and +instantiate objects in discrete chunks, yielding them one at a +time. For a ``QuerySet`` which returns a large number of objects, this +often results in better performance and a significant reduction in +memory use. + +Note that using ``iterator()`` on a ``QuerySet`` which has already +been evaluated will force it to evaluate again, repeating the query. + +.. _iterator: http://www.python.org/dev/peps/pep-0234/ + ``latest(field_name=None)`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/django-admin.txt b/docs/django-admin.txt index cdd31a2c48..68fcad24fe 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -627,14 +627,34 @@ This is useful in a number of ways: in any way, knowing that whatever data changes you're making are only being made to a test database. -Note that this server can only run on the default port on localhost; it does -not yet accept a ``host`` or ``port`` parameter. - -Also note that it does *not* automatically detect changes to your Python source -code (as ``runserver`` does). It does, however, detect changes to templates. +Note that this server does *not* automatically detect changes to your Python +source code (as ``runserver`` does). It does, however, detect changes to +templates. .. _unit tests: ../testing/ +--addrport [port number or ipaddr:port] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Use ``--addrport`` to specify a different port, or IP address and port, from +the default of 127.0.0.1:8000. This value follows exactly the same format and +serves exactly the same function as the argument to the ``runserver`` subcommand. + +Examples: + +To run the test server on port 7000 with ``fixture1`` and ``fixture2``:: + + django-admin.py testserver --addrport 7000 fixture1 fixture2 + django-admin.py testserver fixture1 fixture2 --addrport 8080 + +(The above statements are equivalent. We include both of them to demonstrate +that it doesn't matter whether the options come before or after the +``testserver`` command.) + +To run on 1.2.3.4:7000 with a `test` fixture:: + + django-admin.py testserver --addrport 1.2.3.4:7000 test + --verbosity ~~~~~~~~~~~ diff --git a/docs/fastcgi.txt b/docs/fastcgi.txt index e50b9323bf..78ee9d408c 100644 --- a/docs/fastcgi.txt +++ b/docs/fastcgi.txt @@ -46,9 +46,8 @@ Prerequisite: flup ================== Before you can start using FastCGI with Django, you'll need to install flup_, -which is a Python library for dealing with FastCGI. Make sure to use the latest -Subversion snapshot of flup, as some users have reported stalled pages with -older flup versions. +which is a Python library for dealing with FastCGI. Version 0.5 or newer should +work fine. .. _flup: http://www.saddi.com/software/flup/ diff --git a/docs/form_preview.txt b/docs/form_preview.txt new file mode 100644 index 0000000000..4be7b07a74 --- /dev/null +++ b/docs/form_preview.txt @@ -0,0 +1,97 @@ +============ +Form preview +============ + +Django comes with an optional "form preview" application that helps automate +the following workflow: + +"Display an HTML form, force a preview, then do something with the submission." + +To force a preview of a form submission, all you have to do is write a short +Python class. + +Overview +========= + +Given a ``django.newforms.Form`` subclass that you define, this application +takes care of the following workflow: + + 1. Displays the form as HTML on a Web page. + 2. Validates the form data when it's submitted via POST. + a. If it's valid, displays a preview page. + b. If it's not valid, redisplays the form with error messages. + 3. When the "confirmation" form is submitted from the preview page, calls + a hook that you define -- a ``done()`` method that gets passed the valid + data. + +The framework enforces the required preview by passing a shared-secret hash to +the preview page via hidden form fields. If somebody tweaks the form parameters +on the preview page, the form submission will fail the hash-comparison test. + +How to use ``FormPreview`` +========================== + + 1. Point Django at the default FormPreview templates. There are two ways to + do this: + + * Add ``'django.contrib.formtools'`` to your ``INSTALLED_APPS`` + setting. This will work if your ``TEMPLATE_LOADERS`` setting includes + the ``app_directories`` template loader (which is the case by + default). See the `template loader docs`_ for more. + + * Otherwise, determine the full filesystem path to the + ``django/contrib/formtools/templates`` directory, and add that + directory to your ``TEMPLATE_DIRS`` setting. + + 2. Create a ``FormPreview`` subclass that overrides the ``done()`` method:: + + from django.contrib.formtools import FormPreview + from myapp.models import SomeModel + + class SomeModelFormPreview(FormPreview): + + def done(self, request, cleaned_data): + # Do something with the cleaned_data, then redirect + # to a "success" page. + return HttpResponseRedirect('/form/success') + + This method takes an ``HttpRequest`` object and a dictionary of the form + data after it has been validated and cleaned. It should return an + ``HttpResponseRedirect`` that is the end result of the form being + submitted. + + 3. Change your URLconf to point to an instance of your ``FormPreview`` + subclass:: + + from myapp.preview import SomeModelFormPreview + from myapp.models import SomeModel + from django import newforms as forms + + ...and add the following line to the appropriate model in your URLconf:: + + (r'^post/$', SomeModelFormPreview(forms.models.form_for_model(SomeModel))), + + Or, if you already have a Form class defined for the model:: + + (r'^post/$', SomeModelFormPreview(SomeModelForm)), + + 4. Run the Django server and visit ``/post/`` in your browser. + +.. _template loader docs: ../templates_python/#loader-types + +``FormPreview`` classes +======================= + +A ``FormPreview`` class is a simple Python class that represents the preview +workflow. ``FormPreview`` classes must subclass +``django.contrib.formtools.preview.FormPreview`` and override the ``done()`` +method. They can live anywhere in your codebase. + +``FormPreview`` templates +========================= + +By default, the form is rendered via the template ``formtools/form.html``, and +the preview page is rendered via the template ``formtools.preview.html``. +These values can be overridden for a particular form preview by setting +``preview_template`` and ``form_template`` attributes on the FormPreview +subclass. See ``django/contrib/formtools/templates`` for the default templates. diff --git a/docs/generic_views.txt b/docs/generic_views.txt index 0601aead11..87b82f7adf 100644 --- a/docs/generic_views.txt +++ b/docs/generic_views.txt @@ -201,6 +201,10 @@ a date in the *future* are not included unless you set ``allow_future`` to specified in ``date_field`` is greater than the current date/time. By default, this is ``False``. + * **New in Django development version:** ``template_object_name``: + Designates the name of the template variable to use in the template + context. By default, this is ``'latest'``. + **Template name:** If ``template_name`` isn't specified, this view will use the template @@ -221,10 +225,16 @@ In addition to ``extra_context``, the template's context will be: years that have objects available according to ``queryset``. These are ordered in reverse. This is equivalent to ``queryset.dates(date_field, 'year')[::-1]``. + * ``latest``: The ``num_latest`` objects in the system, ordered descending by ``date_field``. For example, if ``num_latest`` is ``10``, then ``latest`` will be a list of the latest 10 objects in ``queryset``. + **New in Django development version:** This variable's name depends on + the ``template_object_name`` parameter, which is ``'latest'`` by default. + If ``template_object_name`` is ``'foo'``, this variable's name will be + ``foo``. + .. _RequestContext docs: ../templates_python/#subclassing-context-requestcontext ``django.views.generic.date_based.archive_year`` @@ -688,9 +698,11 @@ A page representing a list of objects. * ``paginate_by``: An integer specifying how many objects should be displayed per page. If this is given, the view will paginate objects with ``paginate_by`` objects per page. The view will expect either a ``page`` - query string parameter (via ``GET``) containing a 1-based page - number, or a ``page`` variable specified in the URLconf. See - "Notes on pagination" below. + query string parameter (via ``GET``) or a ``page`` variable specified in + the URLconf. See `Notes on pagination`_ below. + + * ``page``: The current page number, as an integer. This is 1-based. + See `Notes on pagination`_ below. * ``template_name``: The full name of a template to use in rendering the page. This lets you override the default template name (see below). @@ -765,6 +777,9 @@ If the results are paginated, the context will contain these extra variables: * ``hits``: The total number of objects across *all* pages, not just this page. + * **New in Django development version:** ``page_range``: A list of the + page numbers that are available. This is 1-based. + Notes on pagination ~~~~~~~~~~~~~~~~~~~ @@ -777,12 +792,29 @@ specify the page number in the URL in one of two ways: (r'^objects/page(?P<page>[0-9]+)/$', 'object_list', dict(info_dict)) * Pass the page number via the ``page`` query-string parameter. For - example, a URL would look like this: + example, a URL would look like this:: /objects/?page=3 -In both cases, ``page`` is 1-based, not 0-based, so the first page would be -represented as page ``1``. + * To loop over all the available page numbers, use the ``page_range`` + variable. You can iterate over the list provided by ``page_range`` + to create a link to every page of results. + +These values and lists are is 1-based, not 0-based, so the first page would be +represented as page ``1``. + +**New in Django development version:** + +As a special case, you are also permitted to use +``last`` as a value for ``page``:: + + /objects/?page=last + +This allows you to access the final page of results without first having to +determine how many pages there are. + +Note that ``page`` *must* be either a valid page number or the value ``last``; +any other value for ``page`` will result in a 404 error. ``django.views.generic.list_detail.object_detail`` -------------------------------------------------- diff --git a/docs/i18n.txt b/docs/i18n.txt index 38252edeb1..25191e9402 100644 --- a/docs/i18n.txt +++ b/docs/i18n.txt @@ -27,21 +27,8 @@ Essentially, Django does two things: * It uses these hooks to translate Web apps for particular users according to their language preferences. -How to internationalize your app: in three steps ------------------------------------------------- - - 1. Embed translation strings in your Python code and templates. - 2. Get translations for those strings, in whichever languages you want to - support. - 3. Activate the locale middleware in your Django settings. - -.. admonition:: Behind the scenes - - Django's translation machinery uses the standard ``gettext`` module that - comes with Python. - -If you don't need internationalization -====================================== +If you don't need internationalization in your app +================================================== Django's internationalization hooks are on by default, and that means there's a bit of i18n-related overhead in certain places of the framework. If you don't @@ -55,8 +42,21 @@ from your ``TEMPLATE_CONTEXT_PROCESSORS`` setting. .. _documentation for USE_I18N: ../settings/#use-i18n -How to specify translation strings -================================== +If you do need internationalization: three steps +================================================ + + 1. Embed translation strings in your Python code and templates. + 2. Get translations for those strings, in whichever languages you want to + support. + 3. Activate the locale middleware in your Django settings. + +.. admonition:: Behind the scenes + + Django's translation machinery uses the standard ``gettext`` module that + comes with Python. + +1. How to specify translation strings +===================================== Translation strings specify "This text should be translated." These strings can appear in your Python code and templates. It's your responsibility to mark @@ -295,7 +295,7 @@ string, so they don't need to be aware of translations. .. _Django templates: ../templates_python/ Working with lazy translation objects -===================================== +------------------------------------- Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models and utility functions is a common operation. When you're working with these @@ -305,7 +305,7 @@ convert them to strings, because they should be converted as late as possible couple of helper functions. Joining strings: string_concat() --------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Standard Python string joins (``''.join([...])``) will not work on lists containing lazy translation objects. Instead, you can use @@ -324,7 +324,7 @@ strings when ``result`` itself is used in a string (usually at template rendering time). The allow_lazy() decorator --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ Django offers many utility functions (particularly in ``django.utils``) that take a string as their first argument and do something to that string. These @@ -359,8 +359,8 @@ Using this decorator means you can write your function and assume that the input is a proper string, then add support for lazy translation objects at the end. -How to create language files -============================ +2. How to create language files +=============================== Once you've tagged your strings for later translation, you need to write (or obtain) the language translations themselves. Here's how that works. @@ -393,7 +393,7 @@ To create or update a message file, run this command:: ...where ``de`` is the language code for the message file you want to create. The language code, in this case, is in locale format. For example, it's -``pt_BR`` for Brazilian Portugese and ``de_AT`` for Austrian German. +``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian German. The script should be run from one of three places: @@ -490,8 +490,8 @@ That's it. Your translations are ready for use. .. _Submitting and maintaining translations: ../contributing/ -How Django discovers language preference -======================================== +3. How Django discovers language preference +=========================================== Once you've prepared your translations -- or, if you just want to use the translations that come with Django -- you'll just need to activate translation @@ -546,7 +546,7 @@ following this algorithm: Notes: * In each of these places, the language preference is expected to be in the - standard language format, as a string. For example, Brazilian Portugese + standard language format, as a string. For example, Brazilian Portuguese is ``pt-br``. * If a base language is available but the sublanguage specified is not, Django uses the base language. For example, if a user specifies ``de-at`` @@ -629,44 +629,6 @@ in ``request.LANGUAGE_CODE``. .. _session: ../sessions/ .. _request object: ../request_response/#httprequest-objects -The ``set_language`` redirect view -================================== - -As a convenience, Django comes with a view, ``django.views.i18n.set_language``, -that sets a user's language preference and redirects back to the previous page. - -Activate this view by adding the following line to your URLconf:: - - (r'^i18n/', include('django.conf.urls.i18n')), - -(Note that this example makes the view available at ``/i18n/setlang/``.) - -The view expects to be called via the ``GET`` method, with a ``language`` -parameter set in the query string. If session support is enabled, the view -saves the language choice in the user's session. Otherwise, it saves the -language choice in a ``django_language`` cookie. - -After setting the language choice, Django redirects the user, following this -algorithm: - - * Django looks for a ``next`` parameter in the query string. - * If that doesn't exist, or is empty, Django tries the URL in the - ``Referer`` header. - * If that's empty -- say, if a user's browser suppresses that header -- - then the user will be redirected to ``/`` (the site root) as a fallback. - -Here's example HTML template code:: - - <form action="/i18n/setlang/" method="get"> - <input name="next" type="hidden" value="/next/page/" /> - <select name="language"> - {% for lang in LANGUAGES %} - <option value="{{ lang.0 }}">{{ lang.1 }}</option> - {% endfor %} - </select> - <input type="submit" value="Go" /> - </form> - Using translations in your own projects ======================================= @@ -728,6 +690,44 @@ The easiest way out is to store applications that are not part of the project connected to your explicit project and not strings that are distributed independently. +The ``set_language`` redirect view +================================== + +As a convenience, Django comes with a view, ``django.views.i18n.set_language``, +that sets a user's language preference and redirects back to the previous page. + +Activate this view by adding the following line to your URLconf:: + + (r'^i18n/', include('django.conf.urls.i18n')), + +(Note that this example makes the view available at ``/i18n/setlang/``.) + +The view expects to be called via the ``POST`` method, with a ``language`` +parameter set in request. If session support is enabled, the view +saves the language choice in the user's session. Otherwise, it saves the +language choice in a ``django_language`` cookie. + +After setting the language choice, Django redirects the user, following this +algorithm: + + * Django looks for a ``next`` parameter in ``POST`` request. + * If that doesn't exist, or is empty, Django tries the URL in the + ``Referrer`` header. + * If that's empty -- say, if a user's browser suppresses that header -- + then the user will be redirected to ``/`` (the site root) as a fallback. + +Here's example HTML template code:: + + <form action="/i18n/setlang/" method="post"> + <input name="next" type="hidden" value="/next/page/" /> + <select name="language"> + {% for lang in LANGUAGES %} + <option value="{{ lang.0 }}">{{ lang.1 }}</option> + {% endfor %} + </select> + <input type="submit" value="Go" /> + </form> + Translations and JavaScript =========================== @@ -752,7 +752,7 @@ The main solution to these problems is the ``javascript_catalog`` view, which sends out a JavaScript code library with functions that mimic the ``gettext`` interface, plus an array of translation strings. Those translation strings are taken from the application, project or Django core, according to what you -specify in either the {{{info_dict}}} or the URL. +specify in either the info_dict or the URL. You hook it up like this:: @@ -817,8 +817,8 @@ pluralizations). Creating JavaScript translation catalogs ---------------------------------------- -You create and update the translation catalogs the same way as the other Django -translation catalogs -- with the {{{make-messages.py}}} tool. The only +You create and update the translation catalogs the same way as the other +Django translation catalogs -- with the make-messages.py tool. The only difference is you need to provide a ``-d djangojs`` parameter, like this:: make-messages.py -d djangojs -l de @@ -827,13 +827,13 @@ This would create or update the translation catalog for JavaScript for German. After updating translation catalogs, just run ``compile-messages.py`` the same way as you do with normal Django translation catalogs. -Specialities of Django translation +Specialties of Django translation ================================== -If you know ``gettext``, you might note these specialities in the way Django +If you know ``gettext``, you might note these specialties in the way Django does translation: - * The string domain is ``django`` or ``djangojs``. The string domain is + * The string domain is ``django`` or ``djangojs``. This string domain is used to differentiate between different programs that store their data in a common message-file library (usually ``/usr/share/locale/``). The ``django`` domain is used for python and template translation strings @@ -841,5 +841,5 @@ does translation: domain is only used for JavaScript translation catalogs to make sure that those are as small as possible. * Django doesn't use ``xgettext`` alone. It uses Python wrappers around - ``xgettext`` and ``msgfmt``. That's mostly for convenience. + ``xgettext`` and ``msgfmt``. This is mostly for convenience. diff --git a/docs/install.txt b/docs/install.txt index 082000149f..173f4941ee 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -67,6 +67,16 @@ installed. * If you're using Oracle, you'll need cx_Oracle_, version 4.3.1 or higher. +If you plan to use Django's ``manage.py syncdb`` command to +automatically create database tables for your models, you'll need to +ensure that Django has permission to create tables in the database +you're using; if you plan to manually create the tables, you can +simply grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and ``DELETE`` +permissions. Django does not issue ``ALTER TABLE`` statements, and so +will not require permission to do so. If you will be using Django's +`testing framework`_ with data fixtures, Django will need permission +to create a temporary test database. + .. _PostgreSQL: http://www.postgresql.org/ .. _MySQL: http://www.mysql.com/ .. _Django's ticket system: http://code.djangoproject.com/report/1 @@ -78,6 +88,7 @@ installed. .. _MySQL backend: ../databases/ .. _cx_Oracle: http://www.python.net/crew/atuining/cx_Oracle/ .. _Oracle: http://www.oracle.com/ +.. _testing framework: ../testing/ Remove any old versions of Django ================================= @@ -127,16 +138,24 @@ Installing an official release 1. Download the latest release from our `download page`_. - 2. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``). + 2. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``, + where ``NNN`` is the version number of the latest release). + If you're using Windows, you can download the command-line tool + bsdtar_ to do this, or you can use a GUI-based tool such as 7-zip_. - 3. Change into the downloaded directory (e.g. ``cd Django-NNN``). + 3. Change into the directory created in step 2 (e.g. ``cd Django-NNN``). - 4. Run ``sudo python setup.py install``. + 4. If you're using Linux, Mac OS X or some other flavor of Unix, enter + the command ``sudo python setup.py install`` at the shell prompt. + If you're using Windows, start up a command shell with administrator + privileges and run the command ``setup.py install``. -The command will install Django in your Python installation's ``site-packages`` -directory. +These commands will install Django in your Python installation's +``site-packages`` directory. .. _distribution specific notes: ../distributions/ +.. _bsdtar: http://gnuwin32.sourceforge.net/packages/bsdtar.htm +.. _7-zip: http://www.7-zip.org/ Installing the development version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -144,34 +163,55 @@ Installing the development version If you'd like to be able to update your Django code occasionally with the latest bug fixes and improvements, follow these instructions: -1. Make sure you have Subversion_ installed. -2. Check out the Django code into your Python ``site-packages`` directory. +1. Make sure that you have Subversion_ installed, and that you can run its + commands from a shell. (Enter ``svn help`` at a shell prompt to test + this.) + +2. Check out Django's main development branch (the 'trunk') like so:: + + svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk - On Linux / Mac OSX / Unix, do this:: +3. Next, make sure that the Python interpreter can load Django's code. There + are various ways of accomplishing this. One of the most convenient, on + Linux, Mac OSX or other Unix-like systems, is to use a symbolic link:: - svn co http://code.djangoproject.com/svn/django/trunk/ django_src - ln -s `pwd`/django_src/django SITE-PACKAGES-DIR/django + ln -s `pwd`/django-trunk/django SITE-PACKAGES-DIR/django (In the above line, change ``SITE-PACKAGES-DIR`` to match the location of your system's ``site-packages`` directory, as explained in the "Where are my ``site-packages`` stored?" section above.) - On Windows, do this:: + Alternatively, you can define your ``PYTHONPATH`` environment variable + so that it includes the ``django`` subdirectory of ``django-trunk``. + This is perhaps the most convenient solution on Windows systems, which + don't support symbolic links. (Environment variables can be defined on + Windows systems `from the Control Panel`_.) + + .. admonition:: What about Apache and mod_python? + + If you take the approach of setting ``PYTHONPATH``, you'll need to + remember to do the same thing in your Apache configuration once you + deploy your production site. Do this by setting ``PythonPath`` in your + Apache configuration file. + + More information about deployment is available, of course, in our + `How to use Django with mod_python`_ documentation. - svn co http://code.djangoproject.com/svn/django/trunk/django c:\Python24\lib\site-packages\django + .. _How to use Django with mod_python: ../modpython/ -3. Copy the file ``django_src/django/bin/django-admin.py`` to somewhere on your - system path, such as ``/usr/local/bin`` (Unix) or ``C:\Python24\Scripts`` +4. Copy the file ``django-trunk/django/bin/django-admin.py`` to somewhere on + your system path, such as ``/usr/local/bin`` (Unix) or ``C:\Python24\Scripts`` (Windows). This step simply lets you type ``django-admin.py`` from within any directory, rather than having to qualify the command with the full path to the file. -You *don't* have to run ``python setup.py install``, because that command -takes care of steps 2 and 3 for you. +You *don't* have to run ``python setup.py install``, because you've already +carried out the equivalent actions in steps 3 and 4. When you want to update your copy of the Django source code, just run the -command ``svn update`` from within the ``django`` directory. When you do this, -Subversion will automatically download any changes. +command ``svn update`` from within the ``django-trunk`` directory. When you do +this, Subversion will automatically download any changes. .. _`download page`: http://www.djangoproject.com/download/ .. _Subversion: http://subversion.tigris.org/ +.. _from the Control Panel: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sysdm_advancd_environmnt_addchange_variable.mspx diff --git a/docs/model-api.txt b/docs/model-api.txt index efe62baf16..1f0bb60285 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -148,7 +148,7 @@ and in Django's validation. Django veterans: Note that the argument is now called ``max_length`` to provide consistency throughout Django. There is full legacy support for -the old ``maxlength`` argument, but ``max_length`` is prefered. +the old ``maxlength`` argument, but ``max_length`` is preferred. ``CommaSeparatedIntegerField`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -178,7 +178,8 @@ A date field. Has a few extra optional arguments: ====================== =================================================== The admin represents this as an ``<input type="text">`` with a JavaScript -calendar and a shortcut for "Today." +calendar, and a shortcut for "Today." The JavaScript calendar will always start +the week on a Sunday. ``DateTimeField`` ~~~~~~~~~~~~~~~~~ @@ -221,8 +222,10 @@ The admin represents this as an ``<input type="text">`` (a single-line input). ~~~~~~~~~~~~~~ A ``CharField`` that checks that the value is a valid e-mail address. -This doesn't accept ``max_length``; its ``max_length`` is automatically set to -75. + +In Django 0.96, this doesn't accept ``max_length``; its ``max_length`` is +automatically set to 75. In the Django development version, ``max_length`` is +set to 75 by default, but you can specify it to override default behavior. ``FileField`` ~~~~~~~~~~~~~ @@ -1224,6 +1227,13 @@ together. It's used in the Django admin and is enforced at the database level (i.e., the appropriate ``UNIQUE`` statements are included in the ``CREATE TABLE`` statement). +**New in Django development version** + +For convenience, unique_together can be a single list when dealing +with a single set of fields:: + + unique_together = ("driver", "restaurant") + ``verbose_name`` ---------------- @@ -1550,8 +1560,8 @@ Finally, note that in order to use ``list_display_links``, you must define Set ``list_filter`` to activate filters in the right sidebar of the change list page of the admin. This should be a list of field names, and each specified -field should be either a ``BooleanField``, ``DateField``, ``DateTimeField`` -or ``ForeignKey``. +field should be either a ``BooleanField``, ``CharField``, ``DateField``, +``DateTimeField``, ``IntegerField`` or ``ForeignKey``. This example, taken from the ``django.contrib.auth.models.User`` model, shows how both ``list_display`` and ``list_filter`` work:: diff --git a/docs/modpython.txt b/docs/modpython.txt index cbed0ee8c3..4a8c169a51 100644 --- a/docs/modpython.txt +++ b/docs/modpython.txt @@ -83,7 +83,7 @@ need to write your ``PythonPath`` directive as:: With this path, ``import weblog`` and ``import mysite.settings`` will both work. If you had ``import blogroll`` in your code somewhere and ``blogroll`` lived under the ``weblog/`` directory, you would *also* need to add -``/var/production/django-apps/weblog/`` to your ``PythonPath``. Remember: the +``/usr/local/django-apps/weblog/`` to your ``PythonPath``. Remember: the **parent directories** of anything you import directly must be on the Python path. diff --git a/docs/newforms.txt b/docs/newforms.txt index 499892234c..1c13de0316 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -557,6 +557,29 @@ method you're using:: <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p> <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p> +Customizing the error list format +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, forms use ``django.newforms.util.ErrorList`` to format validation +errors. If you'd like to use an alternate class for displaying errors, you can +pass that in at construction time:: + + >>> from django.newforms.util import ErrorList + >>> class DivErrorList(ErrorList): + ... def __unicode__(self): + ... return self.as_divs() + ... def as_divs(self): + ... if not self: return u'' + ... return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self]) + >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList) + >>> f.as_p() + <div class="errorlist"><div class="error">This field is required.</div></div> + <p>Subject: <input type="text" name="subject" maxlength="100" /></p> + <p>Message: <input type="text" name="message" value="Hi there" /></p> + <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div> + <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p> + <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p> + More granular output ~~~~~~~~~~~~~~~~~~~~ @@ -756,6 +779,27 @@ form data *and* file data:: # Unbound form with a image field >>> f = ContactFormWithMugshot() +Testing for multipart forms +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you're writing reusable views or templates, you may not know ahead of time +whether your form is a multipart form or not. The ``is_multipart()`` method +tells you whether the form requires multipart encoding for submission:: + + >>> f = ContactFormWithMugshot() + >>> f.is_multipart() + True + +Here's an example of how you might use this in a template:: + + {% if form.is_multipart %} + <form enctype="multipart/form-data" method="post" action="/foo/"> + {% else %} + <form method="post" action="/foo/"> + {% endif %} + {% form %} + </form> + Subclassing forms ----------------- @@ -965,7 +1009,7 @@ validation if a particular field's value is not given. ``initial`` values are ~~~~~~~~~~ The ``widget`` argument lets you specify a ``Widget`` class to use when -rendering this ``Field``. See "Widgets"_ below for more information. +rendering this ``Field``. See `Widgets`_ below for more information. ``help_text`` ~~~~~~~~~~~~~ @@ -1890,12 +1934,23 @@ field on the model, you could define the callback:: ... else: ... return field.formfield(**kwargs) - >>> ArticleForm = form_for_model(formfield_callback=my_callback) + >>> ArticleForm = form_for_model(Article, formfield_callback=my_callback) Note that your callback needs to handle *all* possible model field types, not just the ones that you want to behave differently to the default. That's why this example has an ``else`` clause that implements the default behavior. +.. warning:: + The field that is passed into the ``formfield_callback`` function in + ``form_for_model()`` and ``form_for_instance`` is the field instance from + your model's class. You **must not** alter that object at all; treat it + as read-only! + + If you make any alterations to that object, it will affect any future + users of the model class, because you will have changed the field object + used to construct the class. This is almost certainly what you don't want + to have happen. + Finding the model associated with a form ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/request_response.txt b/docs/request_response.txt index 867464226a..bf914fb5ff 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -161,6 +161,18 @@ Methods Example: ``"/music/bands/the_beatles/?print=true"`` +``build_absolute_uri(location)`` + **New in Django development version** + + Returns the absolute URI form of ``location``. If no location is provided, + the location will be set to ``request.get_full_path()``. + + If the location is already an absolute URI, it will not be altered. + Otherwise the absolute URI is built using the server variables available in + this request. + + Example: ``"http://example.com/music/bands/the_beatles/?print=true"`` + ``is_secure()`` Returns ``True`` if the request is secure; that is, if it was made with HTTPS. @@ -183,6 +195,9 @@ subclass of dictionary. Exceptions are outlined here: * ``__getitem__(key)`` -- Returns the value for the given key. If the key has more than one value, ``__getitem__()`` returns the last value. + Raises ``django.utils.datastructure.MultiValueDictKeyError`` if the key + does not exist. (This is a subclass of Python's standard ``KeyError``, + so you can stick to catching ``KeyError``.) * ``__setitem__(key, value)`` -- Sets the given key to ``[value]`` (a Python list whose single element is ``value``). Note that this, as diff --git a/docs/settings.txt b/docs/settings.txt index 3f98296778..2e6185f444 100644 --- a/docs/settings.txt +++ b/docs/settings.txt @@ -253,9 +253,14 @@ DATABASE_ENGINE Default: ``''`` (Empty string) -The database backend to use. Either ``'postgresql_psycopg2'``, -``'postgresql'``, ``'mysql'``, ``'mysql_old'``, ``'sqlite3'``, -``'oracle'``, or ``'ado_mssql'``. +The database backend to use. The build-in database backends are +``'postgresql_psycopg2'``, ``'postgresql'``, ``'mysql'``, ``'mysql_old'``, +``'sqlite3'``, ``'oracle'``, or ``'ado_mssql'``. + +You can also use a database backend that doesn't ship with Django by +setting ``DATABASE_ENGINE`` to a fully-qualified path (i.e. +``mypackage.backends.whatever``). Writing a whole new database backend from +scratch is left as an exercise to the reader. DATABASE_HOST ------------- @@ -325,7 +330,8 @@ The default formatting to use for date fields on Django admin change-list pages -- and, possibly, by other parts of the system. See `allowed date format strings`_. -See also DATETIME_FORMAT, TIME_FORMAT, YEAR_MONTH_FORMAT and MONTH_DAY_FORMAT. +See also ``DATETIME_FORMAT``, ``TIME_FORMAT``, ``YEAR_MONTH_FORMAT`` +and ``MONTH_DAY_FORMAT``. .. _allowed date format strings: ../templates/#now @@ -338,7 +344,8 @@ The default formatting to use for datetime fields on Django admin change-list pages -- and, possibly, by other parts of the system. See `allowed date format strings`_. -See also DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT, YEAR_MONTH_FORMAT and MONTH_DAY_FORMAT. +See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``, +``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``. .. _allowed date format strings: ../templates/#now @@ -350,8 +357,8 @@ Default: ``False`` A boolean that turns on/off debug mode. If you define custom settings, django/views/debug.py has a ``HIDDEN_SETTINGS`` -regular expression which will hide from the DEBUG view anything that contins -``'SECRET``, ``PASSWORD``, or ``PROFANITIES'``. This allows untrusted users to +regular expression which will hide from the DEBUG view anything that contains +``'SECRET'``, ``'PASSWORD'``, or ``'PROFANITIES'``. This allows untrusted users to be able to give backtraces without seeing sensitive (or offensive) settings. Still, note that there are always going to be sections of your debug output that @@ -656,8 +663,8 @@ drilldown, the header for a given day displays the day and month. Different locales have different formats. For example, U.S. English would say "January 1," whereas Spanish might say "1 Enero." -See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT, -TIME_FORMAT and YEAR_MONTH_FORMAT. +See `allowed date format strings`_. See also ``DATE_FORMAT``, +``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``YEAR_MONTH_FORMAT``. PREPEND_WWW ----------- @@ -815,7 +822,7 @@ highlighted. Note that Django only displays fancy error pages if ``DEBUG`` is ``True``, so you'll want to set that to take advantage of this setting. -See also DEBUG. +See also ``DEBUG``. TEMPLATE_DIRS ------------- @@ -905,8 +912,8 @@ The default formatting to use for time fields on Django admin change-list pages -- and, possibly, by other parts of the system. See `allowed date format strings`_. -See also DATE_FORMAT, DATETIME_FORMAT, TIME_FORMAT, YEAR_MONTH_FORMAT and -MONTH_DAY_FORMAT. +See also ``DATE_FORMAT``, ``DATETIME_FORMAT``, ``TIME_FORMAT``, +``YEAR_MONTH_FORMAT`` and ``MONTH_DAY_FORMAT``. .. _allowed date format strings: ../templates/#now @@ -980,8 +987,8 @@ drilldown, the header for a given month displays the month and the year. Different locales have different formats. For example, U.S. English would say "January 2006," whereas another locale might say "2006/January." -See `allowed date format strings`_. See also DATE_FORMAT, DATETIME_FORMAT, -TIME_FORMAT and MONTH_DAY_FORMAT. +See `allowed date format strings`_. See also ``DATE_FORMAT``, +``DATETIME_FORMAT``, ``TIME_FORMAT`` and ``MONTH_DAY_FORMAT``. .. _cache docs: ../cache/ .. _middleware docs: ../middleware/ diff --git a/docs/shortcuts.txt b/docs/shortcuts.txt new file mode 100644 index 0000000000..6c55486b5f --- /dev/null +++ b/docs/shortcuts.txt @@ -0,0 +1,143 @@ +========================= +Django shortcut functions +========================= + +The package ``django.shortcuts`` collects helper functions and classes that +"span" multiple levels of MVC. In other words, these functions/classes +introduce controlled coupling for convenience's sake. + +``render_to_response()`` +======================== + +``django.shortcuts.render_to_response`` renders a given template with a given +context dictionary and returns an ``HttpResponse`` object with that rendered +text. + +Required arguments +------------------ + +``template`` + The full name of a template to use. + +Optional arguments +------------------ + +``context`` + A dictionary of values to add to the template context. By default, this + is an empty dictionary. If a value in the dictionary is callable, the + view will call it just before rendering the template. + +``mimetype`` + **New in Django development version:** The MIME type to use for the + resulting document. Defaults to the value of the ``DEFAULT_CONTENT_TYPE`` + setting. + +Example +------- + +The following example renders the template ``myapp/index.html`` with the +MIME type ``application/xhtml+xml``:: + + from django.shortcuts import render_to_response + + def my_view(request): + # View code here... + return render_to_response('myapp/index.html', {"foo": "bar"}, + mimetype="application/xhtml+xml") + +This example is equivalent to:: + + from django.http import HttpResponse + from django.template import Context, loader + + def my_view(request): + # View code here... + t = loader.get_template('myapp/template.html') + c = Context({'foo': 'bar'}) + r = HttpResponse(t.render(c), + mimetype="application/xhtml+xml") + +.. _an HttpResponse object: ../request_response/#httpresponse-objects + +``get_object_or_404`` +===================== + +``django.shortcuts.get_object_or_404`` calls `get()`_ on a given model +manager, but it raises ``django.http.Http404`` instead of the model's +``DoesNotExist`` exception. + +Required arguments +------------------ + +``klass`` + A ``Model``, ``Manager`` or ``QuerySet`` instance from which to get the + object. + +``**kwargs`` + Lookup parameters, which should be in the format accepted by ``get()`` and + ``filter()``. + +Example +------- + +The following example gets the object with the primary key of 1 from +``MyModel``:: + + from django.shortcuts import get_object_or_404 + + def my_view(request): + my_object = get_object_or_404(MyModel, pk=1) + +This example is equivalent to:: + + from django.http import Http404 + + def my_view(request): + try: + my_object = MyModel.object.get(pk=1) + except MyModel.DoesNotExist: + raise Http404 + +Note: As with ``get()``, an ``AssertionError`` will be raised if more than +one object is found. + +.. _get(): ../db-api/#get-kwargs + +``get_list_or_404`` +=================== + +``django.shortcuts.get_list_or_404`` returns the result of `filter()`_ on a +given model manager, raising ``django.http.Http404`` if the resulting list is +empty. + +Required arguments +------------------ + +``klass`` + A ``Model``, ``Manager`` or ``QuerySet`` instance from which to get the + object. + +``**kwargs`` + Lookup parameters, which should be in the format accepted by ``get()`` and + ``filter()``. + +Example +------- + +The following example gets all published objects from ``MyModel``:: + + from django.shortcuts import get_list_or_404 + + def my_view(request): + my_objects = get_list_or_404(MyModel, published=True) + +This example is equivalent to:: + + from django.http import Http404 + + def my_view(request): + my_objects = MyModels.object.filter(published=True) + if not my_objects: + raise Http404 + +.. _filter(): ../db-api/#filter-kwargs diff --git a/docs/sites.txt b/docs/sites.txt index 90a9d0f90f..5896afcf41 100644 --- a/docs/sites.txt +++ b/docs/sites.txt @@ -213,6 +213,31 @@ To do this, you can use the sites framework. A simple example:: >>> 'http://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url()) 'http://example.com/mymodel/objects/3/' +Caching the current ``Site`` object +=================================== + +**New in Django development version** + +As the current site is stored in the database, each call to +``Site.objects.get_current()`` could result in a database query. But Django is a +little cleverer than that: on the first request, the current site is cached, and +any subsequent call returns the cached data instead of hitting the database. + +If for any reason you want to force a database query, you can tell Django to +clear the cache using ``Site.objects.clear_cache()``:: + + # First call; current site fetched from database. + current_site = Site.objects.get_current() + # ... + + # Second call; current site fetched from cache. + current_site = Site.objects.get_current() + # ... + + # Force a database query for the third call. + Site.objects.clear_cache() + current_site = Site.objects.get_current() + The ``CurrentSiteManager`` ========================== @@ -316,6 +341,9 @@ Here's how Django uses the sites framework: * The shortcut view (``django.views.defaults.shortcut``) uses the domain of the current ``Site`` object when calculating an object's URL. + * In the admin framework, the ''view on site'' link uses the current + ``Site`` to work out the domain for the site that it will redirect to. + .. _redirects framework: ../redirects/ .. _flatpages framework: ../flatpages/ .. _syndication framework: ../syndication_feeds/ diff --git a/docs/templates.txt b/docs/templates.txt index 9f2bec1c8b..9adf15731b 100644 --- a/docs/templates.txt +++ b/docs/templates.txt @@ -366,25 +366,36 @@ Ignore everything between ``{% comment %}`` and ``{% endcomment %}`` cycle ~~~~~ -Cycle among the given strings each time this tag is encountered. +**Changed in Django development version** +Cycle among the given strings or variables each time this tag is encountered. -Within a loop, cycles among the given strings each time through the loop:: +Within a loop, cycles among the given strings/variables each time through the +loop:: {% for o in some_list %} - <tr class="{% cycle row1,row2 %}"> + <tr class="{% cycle 'row1' 'row2' rowvar %}"> ... </tr> {% endfor %} - + Outside of a loop, give the values a unique name the first time you call it, then use that name each successive time through:: - <tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr> + <tr class="{% cycle 'row1' 'row2' rowvar as rowcolors %}">...</tr> <tr class="{% cycle rowcolors %}">...</tr> <tr class="{% cycle rowcolors %}">...</tr> -You can use any number of values, separated by commas. Make sure not to put -spaces between the values -- only commas. +You can use any number of values, separated by spaces. Values enclosed in +single (') or double quotes (") are treated as string literals, while values +without quotes are assumed to refer to context variables. + +You can also separate values with commas:: + + {% cycle row1,row2,row3 %} + +In this syntax, each value will be interpreted as literal text. The +comma-based syntax exists for backwards-compatibility, and should not be +used for new projects. debug ~~~~~ @@ -1124,12 +1135,15 @@ Returns a boolean of whether the value's length is the argument. linebreaks ~~~~~~~~~~ -Converts newlines into ``<p>`` and ``<br />`` tags. +Replaces line breaks in plain text with appropriate HTML; a single +newline becomes an HTML line break (``<br />``) and a new line +followed by a blank line becomes a paragraph break (``</p>``). linebreaksbr ~~~~~~~~~~~~ -Converts newlines into ``<br />`` tags. +Converts all newlines in a piece of plain text to HTML line breaks +(``<br />``). linenumbers ~~~~~~~~~~~ @@ -1405,6 +1419,12 @@ A collection of template filters that implement these common markup languages: * Markdown * ReST (ReStructured Text) +See the `markup section`_ of the `add-ons documentation`_ for more +information. + +.. _markup section: ../add_ons/#markup +.. _add-ons documentation: ../add_ons/ + django.contrib.webdesign ------------------------ @@ -1420,4 +1440,4 @@ Read the document `The Django template language: For Python programmers`_ if you're interested in learning the template system from a technical perspective -- how it works and how to extend it. -.. _The Django template language: For Python programmers: ../templates_python/ +.. _The Django template language\: For Python programmers: ../templates_python/ diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 261eaedf74..232f54061f 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -555,6 +555,38 @@ template loaders that come with Django: Django uses the template loaders in order according to the ``TEMPLATE_LOADERS`` setting. It uses each loader until a loader finds a match. +The ``render_to_string()`` shortcut +=================================== + +To cut down on the repetitive nature of loading and rendering +templates, Django provides a shortcut function which largely +automates the process: ``render_to_string()`` in +``django.template.loader``, which loads a template, renders it and +returns the resulting string:: + + from django.template.loader import render_to_string + rendered = render_to_string('my_template.html', { 'foo': 'bar' }) + +The ``render_to_string`` shortcut takes one required argument -- +``template_name``, which should be the name of the template to load +and render -- and two optional arguments:: + + dictionary + A dictionary to be used as variables and values for the + template's context. This can also be passed as the second + positional argument. + + context_instance + An instance of ``Context`` or a subclass (e.g., an instance of + ``RequestContext``) to use as the template's context. This can + also be passed as the third positional argument. + +See also the `render_to_response()`_ shortcut, which calls +``render_to_string`` and feeds the result into an ``HttpResponse`` +suitable for returning directly from a view. + +.. _render_to_response(): ../shortcuts/#render-to-response + Extending the template system ============================= @@ -642,7 +674,27 @@ your function. Example:: "Converts a string into all lowercase" return value.lower() -When you've written your filter definition, you need to register it with +Template filters that expect strings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you're writing a template filter that only expects a string as the first +argument, you should use the decorator ``stringfilter``. This will +convert an object to its string value before being passed to your function:: + + from django.template.defaultfilters import stringfilter + + @stringfilter + def lower(value): + return value.lower() + +This way, you'll be able to pass, say, an integer to this filter, and it +won't cause an ``AttributeError`` (because integers don't have ``lower()`` +methods). + +Registering a custom filters +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Once you've written your filter definition, you need to register it with your ``Library`` instance, to make it available to Django's template language:: register.filter('cut', cut) @@ -658,28 +710,18 @@ If you're using Python 2.4 or above, you can use ``register.filter()`` as a decorator instead:: @register.filter(name='cut') + @stringfilter def cut(value, arg): return value.replace(arg, '') @register.filter + @stringfilter def lower(value): return value.lower() If you leave off the ``name`` argument, as in the second example above, Django will use the function's name as the filter name. -Template filters which expect strings -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you are writing a template filter which only expects a string as the first -argument, you should use the included decorator ``stringfilter`` which will convert -an object to it's string value before being passed to your function:: - - from django.template.defaultfilters import stringfilter - - @stringfilter - def lower(value): - return value.lower() - Writing custom template tags ---------------------------- diff --git a/docs/testing.txt b/docs/testing.txt index 22a7e48a7a..04c999cda8 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -137,12 +137,14 @@ When you `run your tests`_, the test runner will find this docstring, notice that portions of it look like an interactive Python session, and execute those lines while checking that the results match. -In the case of model tests, note that the test runner takes care of creating -its own test database. That is, any test that accesses a database -- by -creating and saving model instances, for example -- will not affect your -production database. Each doctest begins with a "blank slate" -- a fresh -database containing an empty table for each model. (See the section on -fixtures, below, for more on this.) +In the case of model tests, note that the test runner takes care of +creating its own test database. That is, any test that accesses a +database -- by creating and saving model instances, for example -- +will not affect your production database. Each doctest begins with a +"blank slate" -- a fresh database containing an empty table for each +model. (See the section on fixtures, below, for more on this.) Note +that to use this feature, the database user Django is connecting as +must have ``CREATE DATABASE`` rights. For more details about how doctest works, see the `standard library documentation for doctest`_ @@ -569,8 +571,8 @@ Testing responses The ``get()`` and ``post()`` methods both return a ``Response`` object. This ``Response`` object is *not* the same as the ``HttpResponse`` object returned -Django views; this object is simpler and has some additional data useful for -tests. +Django views; the test response object has some additional data useful for +test code to verify. Specifically, a ``Response`` object has the following attributes: @@ -582,7 +584,7 @@ Specifically, a ``Response`` object has the following attributes: ``content`` The body of the response, as a string. This is the final page content as rendered by the view, or any error - message (such as the URL for a 302 redirect). + message. ``context`` The template ``Context`` instance that was used to render the template that produced the response content. @@ -591,6 +593,8 @@ Specifically, a ``Response`` object has the following attributes: ``context`` will be a list of ``Context`` objects, in the order in which they were rendered. + ``headers`` The HTTP headers of the response. This is a dictionary. + ``request`` The request data that stimulated the response. ``status_code`` The HTTP status of the response, as an integer. See diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index 77b5b11103..4e97dcd541 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -41,6 +41,16 @@ From the command line, ``cd`` into a directory where you'd like to store your code, then run the command ``django-admin.py startproject mysite``. This will create a ``mysite`` directory in your current directory. +.. admonition:: Max OS X permissions + + If you're using Mac OS X, you may see the message "permission + denied" when you try to run ``django-admin.py startproject``. This + is because, on Unix-based systems like OS X, a file must be marked + as "executable" before it can be run as a program. To do this, open + Terminal.app and navigate (using the `cd` command) to the directory + where ``django-admin.py`` is installed, then run the command + ``chmod +x django-admin.py``. + .. note:: You'll need to avoid naming projects after built-in Python or Django |
