diff options
| author | Boulder Sprinters <boulder-sprinters@djangoproject.com> | 2007-03-09 17:43:46 +0000 |
|---|---|---|
| committer | Boulder Sprinters <boulder-sprinters@djangoproject.com> | 2007-03-09 17:43:46 +0000 |
| commit | 0b7dd14d1f87e2ecef7aacc39fe4189667ed4fdf (patch) | |
| tree | b77497f9de324d38a9c6341e54d2742633e20055 /docs | |
| parent | e17f75551491f5b864c1fc8a97c21d0b2bbf0bcd (diff) | |
boulder-oracle-sprint: Merged to trunk [4692].
git-svn-id: http://code.djangoproject.com/svn/django/branches/boulder-oracle-sprint@4695 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/add_ons.txt | 9 | ||||
| -rw-r--r-- | docs/authentication.txt | 165 | ||||
| -rw-r--r-- | docs/contributing.txt | 62 | ||||
| -rw-r--r-- | docs/db-api.txt | 30 | ||||
| -rw-r--r-- | docs/distributions.txt | 76 | ||||
| -rw-r--r-- | docs/django-admin.txt | 174 | ||||
| -rw-r--r-- | docs/email.txt | 6 | ||||
| -rw-r--r-- | docs/fastcgi.txt | 2 | ||||
| -rw-r--r-- | docs/forms.txt | 12 | ||||
| -rw-r--r-- | docs/generic_views.txt | 8 | ||||
| -rw-r--r-- | docs/install.txt | 31 | ||||
| -rw-r--r-- | docs/model-api.txt | 75 | ||||
| -rw-r--r-- | docs/newforms.txt | 47 | ||||
| -rw-r--r-- | docs/outputting_pdf.txt | 2 | ||||
| -rw-r--r-- | docs/request_response.txt | 115 | ||||
| -rw-r--r-- | docs/settings.txt | 97 | ||||
| -rw-r--r-- | docs/syndication_feeds.txt | 35 | ||||
| -rw-r--r-- | docs/templates.txt | 55 | ||||
| -rw-r--r-- | docs/templates_python.txt | 76 | ||||
| -rw-r--r-- | docs/testing.txt | 229 | ||||
| -rw-r--r-- | docs/tutorial01.txt | 16 | ||||
| -rw-r--r-- | docs/tutorial04.txt | 15 | ||||
| -rw-r--r-- | docs/url_dispatch.txt | 7 |
23 files changed, 1206 insertions, 138 deletions
diff --git a/docs/add_ons.txt b/docs/add_ons.txt index d937eb2141..1756fe5720 100644 --- a/docs/add_ons.txt +++ b/docs/add_ons.txt @@ -139,6 +139,15 @@ See the `flatpages documentation`_. .. _flatpages documentation: ../flatpages/ +localflavor +=========== + +**New in Django development version** + +A collection of various Django snippets that are useful only for a particular +country or culture. For example, ``django.contrib.localflavor.usa.forms`` +contains a ``USZipCodeField`` that you can use to validate U.S. zip codes. + markup ====== diff --git a/docs/authentication.txt b/docs/authentication.txt index ef30879ae0..aff336f67a 100644 --- a/docs/authentication.txt +++ b/docs/authentication.txt @@ -86,10 +86,10 @@ objects in the same way as any other `Django model`_:: myuser.groups.add(group, group,...) myuser.groups.remove(group, group,...) myuser.groups.clear() - myuser.permissions = [permission_list] - myuser.permissions.add(permission, permission, ...) - myuser.permissions.remove(permission, permission, ...] - myuser.permissions.clear() + myuser.user_permissions = [permission_list] + myuser.user_permissions.add(permission, permission, ...) + myuser.user_permissions.remove(permission, permission, ...] + myuser.user_permissions.clear() In addition to those automatic API methods, ``User`` objects have the following custom methods: @@ -317,6 +317,16 @@ This example shows how you might use both ``authenticate()`` and ``login()``:: else: # Return an 'invalid login' error message. +Manually checking a user's password +----------------------------------- + +If you'd like to manually authenticate a user by comparing a +plain-text password to the hashed password in the database, use the +convenience function `django.contrib.auth.models.check_password`. It +takes two arguments: the plain-text password to check, and the full +value of a user's ``password`` field in the database to check against, +and returns ``True`` if they match, ``False`` otherwise. + How to log a user out --------------------- @@ -388,7 +398,7 @@ To do this, add the following line to your URLconf:: (r'^accounts/login/$', 'django.contrib.auth.views.login'), -Here's what ``django.contrib.auth.views.login`` does:: +Here's what ``django.contrib.auth.views.login`` does: * If called via ``GET``, it displays a login form that POSTs to the same URL. More on this in a bit. @@ -444,6 +454,147 @@ block:: .. _forms documentation: ../forms/ .. _site framework docs: ../sites/ +Other built-in views +-------------------- + +In addition to the `login` view, the authentication system includes a +few other useful built-in views: + +``django.contrib.auth.views.logout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +Logs a user out. + +**Optional arguments:** + + * ``template_name``: The full name of a template to display after + logging the user out. This will default to + ``registration/logged_out.html`` if no argument is supplied. + +**Template context:** + + * ``title``: The string "Logged out", localized. + +``django.contrib.auth.views.logout_then_login`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +Logs a user out, then redirects to the login page. + +**Optional arguments:** + + * ``login_url``: The URL of the login page to redirect to. This + will default to ``/accounts/login/`` if not supplied. + +``django.contrib.auth.views.password_change`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +Allows a user to change their password. + +**Optional arguments:** + + * ``template_name``: The full name of a template to use for + displaying the password change form. This will default to + ``registration/password_change_form.html`` if not supplied. + +**Template context:** + + * ``form``: The password change form. + +``django.contrib.auth.views.password_change_done`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +The page shown after a user has changed their password. + +**Optional arguments:** + + * ``template_name``: The full name of a template to use. This will + default to ``registration/password_change_done.html`` if not + supplied. + +``django.contrib.auth.views.password_reset`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +Allows a user to reset their password, and sends them the new password +in an email. + +**Optional arguments:** + + * ``template_name``: The full name of a template to use for + displaying the password reset form. This will default to + ``registration/password_reset_form.html`` if not supplied. + + * ``email_template_name``: The full name of a template to use for + generating the email with the new password. This will default to + ``registration/password_reset_email.html`` if not supplied. + +**Template context:** + + * ``form``: The form for resetting the user's password. + +``django.contrib.auth.views.password_reset_done`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +The page shown after a user has reset their password. + +**Optional arguments:** + + * ``template_name``: The full name of a template to use. This will + default to ``registration/password_reset_done.html`` if not + supplied. + +``django.contrib.auth.views.redirect_to_login`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Description:** + +Redirects to the login page, and then back to another URL after a +successful login. + +**Required arguments:** + + * ``next``: The URL to redirect to after a successful login. + +**Optional arguments:** + + * ``login_url``: The URL of the login page to redirect to. This + will default to ``/accounts/login/`` if not supplied. + +Built-in manipulators +--------------------- + +If you don't want to use the built-in views, but want the convenience +of not having to write manipulators for this functionality, the +authentication system provides several built-in manipulators: + + * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A + manipulator used in the admin interface to change a user's + password. + + * ``django.contrib.auth.forms.AuthenticationForm``: A manipulator + for logging a user in. + + * ``django.contrib.auth.forms.PasswordChangeForm``: A manipulator + for allowing a user to change their password. + + * ``django.contrib.auth.forms.PasswordResetForm``: A manipulator + for resetting a user's password and emailing the new password to + them. + + * ``django.contrib.auth.forms.UserCreationForm``: A manipulator + for creating a new user. + Limiting access to logged-in users that pass a test --------------------------------------------------- @@ -813,13 +964,13 @@ The ``authenticate`` method takes credentials as keyword arguments. Most of the time, it'll just look like this:: class MyBackend: - def authenticate(username=None, password=None): + def authenticate(self, username=None, password=None): # Check the username/password and return a User. But it could also authenticate a token, like so:: class MyBackend: - def authenticate(token=None): + def authenticate(self, token=None): # Check the token and return a User. Either way, ``authenticate`` should check the credentials it gets, and it diff --git a/docs/contributing.txt b/docs/contributing.txt index d802d3eaf6..8364405775 100644 --- a/docs/contributing.txt +++ b/docs/contributing.txt @@ -195,7 +195,7 @@ 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" - The means the ticket has an associated patch_. These will be + This means the ticket has an associated patch_. These will be reviewed to see if the patch is "good". "Needs documentation" @@ -212,6 +212,33 @@ ticket has or needs in order to be "ready for checkin": 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`_ @@ -276,9 +303,11 @@ Please follow these coding standards when writing code for inclusion in Django: def my_view(req, foo): # ... - * Please don't put your name in the code. While we appreciate all - contributions to Django, our policy is not to publish individual - developer names in code -- for instance, at the top of Python modules. + * Our policy is to keep the names of developers and contributors + in the ``AUTHORS`` file distributed with Django, so please don't include + your name in the actual code. Feel free to include a change to the + ``AUTHORS`` file in your patch if you make more than a single trivial + change. Committing code =============== @@ -484,6 +513,29 @@ 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 @@ -491,6 +543,8 @@ If you're using Django 0.95 or earlier and installed it using 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 ================= diff --git a/docs/db-api.txt b/docs/db-api.txt index 99bb30054b..64db3def96 100644 --- a/docs/db-api.txt +++ b/docs/db-api.txt @@ -6,7 +6,7 @@ Once you've created your `data models`_, Django automatically gives you a database-abstraction API that lets you create, retrieve, update and delete objects. This document explains that API. -.. _`data models`: http://www.djangoproject.com/documentation/model_api/ +.. _`data models`: ../model_api/ Throughout this reference, we'll refer to the following models, which comprise a weblog application:: @@ -85,7 +85,7 @@ There's no way to tell what the value of an ID will be before you call unless you explicitly specify ``primary_key=True`` on a field. See the `AutoField documentation`_.) -.. _AutoField documentation: http://www.djangoproject.com/documentation/model_api/#autofield +.. _AutoField documentation: ../model_api/#autofield Explicitly specifying auto-primary-key values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -596,6 +596,21 @@ related ``Person`` *and* the related ``City``:: Note that ``select_related()`` does not follow foreign keys that have ``null=True``. +Usually, using ``select_related()`` can vastly improve performance because your +app can avoid many database calls. However, in situations with deeply nested +sets of relationships ``select_related()`` can sometimes end up following "too +many" relations, and can generate queries so large that they end up being slow. + +In these situations, you can use the ``depth`` argument to ``select_related()`` +to control how many "levels" of relations ``select_related()`` will actually +follow:: + + b = Book.objects.select_related(depth=1).get(id=4) + p = b.author # Doesn't hit the database. + c = p.hometown # Requires a database call. + +The ``depth`` argument is new in the Django development version. + ``extra(select=None, where=None, params=None, tables=None)`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1621,6 +1636,15 @@ For example, this deletes all ``Entry`` objects with a ``pub_date`` year of Entry.objects.filter(pub_date__year=2005).delete() +When Django deletes an object, it emulates the behavior of the SQL +constraint ``ON DELETE CASCADE`` -- in other words, any objects which +had foreign keys pointing at the object to be deleted will be deleted +along with it. For example:: + + b = Blog.objects.get(pk=1) + # This will delete the Blog and all of its Entry objects. + b.delete() + Note that ``delete()`` is the only ``QuerySet`` method that is not exposed on a ``Manager`` itself. This is a safety mechanism to prevent you from accidentally requesting ``Entry.objects.delete()``, and deleting *all* the entries. If you @@ -1777,4 +1801,4 @@ interface to your database. You can access your database via other tools, programming languages or database frameworks; there's nothing Django-specific about your database. -.. _Executing custom SQL: http://www.djangoproject.com/documentation/model_api/#executing-custom-sql +.. _Executing custom SQL: ../model_api/#executing-custom-sql diff --git a/docs/distributions.txt b/docs/distributions.txt new file mode 100644 index 0000000000..a77d3a1959 --- /dev/null +++ b/docs/distributions.txt @@ -0,0 +1,76 @@ +=================================== +Third-party distributions of Django +=================================== + +Several third-party distributors are now providing versions of Django integrated +with their package-management systems. These can make installation and upgrading +much easier for users of Django since the integration includes the ability to +automatically install dependancies (like database adapters) that Django +requires. + +Typically, these packages are based on the latest stable release of Django, so +if you want to use the development version of Django you'll need to follow the +instructions for `installing the development version`_ from our Subversion +repository. + +.. _installing the development version: ../install/#installing-the-development-version + +Linux distributions +=================== + +Debian +------ + +A `packaged version of Django`_ is available for `Debian GNU/Linux`_, and can be +installed from either the "testing" or the "unstable" repositories by typing +``apt-get install python-django``. + +When you install this package, ``apt`` will recommend installing a database +adapter; you should select and install the adapter for whichever database you +plan to use with Django. + +.. _Debian GNU/Linux: http://www.debian.org/ +.. _packaged version of Django: http://packages.debian.org/testing/python/python-django + +Ubuntu +------ + +The Debian ``python-django`` package is also available for `Ubuntu Linux`_, in +the "universe" repository for Ubuntu 7.04 ("Feisty Fawn"). The `current Ubuntu +package`_ is also based on Django 0.95.1 and can be installed in the same +fashion as for Debian. + +.. _Ubuntu Linux: http://www.ubuntu.com/ +.. _current Ubuntu package: http://packages.ubuntu.com/feisty/python/python-django + +Fedora +------ + +A Django package is available for `Fedora Linux`_, in the "Fedora Extras" +repository. The `current Fedora package`_ is based on Django 0.95.1, and can be +installed by typing ``yum install Django``. + +.. _Fedora Linux: http://fedora.redhat.com/ +.. _current Fedora package: http://fedoraproject.org/extras/6/i386/repodata/repoview/Django-0-0.95.1-1.fc6.html + +Gentoo +------ + +A Django build is available for `Gentoo Linux`_, and is based on Django 0.95.1. +The `current Gentoo build`_ can be installed by typing ``emerge Django``. + +.. _Gentoo Linux: http://www.gentoo.org/ +.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django + +For distributors +================ + +If you'd like to package Django for distribution, we'd be happy to help out! +Please join the `django-developers mailing list`_ and introduce yourself. + +We also encourage all distributors to subscribe to the `django-announce mailing +list`_, which is a (very) low-traffic list for announcing new releases of Django +and important bugfixes. + +.. _django-developers mailing list: http://groups.google.com/group/django-developers/ +.. _django-announce mailing list: http://groups.google.com/group/django-announce/ diff --git a/docs/django-admin.txt b/docs/django-admin.txt index 310e8dff0e..371c44e010 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -17,7 +17,12 @@ two things for you before delegating to ``django-admin.py``: The ``django-admin.py`` script should be on your system path if you installed Django via its ``setup.py`` utility. If it's not on your path, you can find it in ``site-packages/django/bin`` within your Python installation. Consider -symlinking to it from some place on your path, such as ``/usr/local/bin``. +symlinking it from some place on your path, such as ``/usr/local/bin``. + +For Windows users, who do not have symlinking functionality available, you +can copy ``django-admin.py`` to a location on your existing path or edit the +``PATH`` settings (under ``Settings - Control Panel - System - Advanced - Environment...``) +to point to its installed location. Generally, when working on a single Django project, it's easier to use ``manage.py``. Use ``django-admin.py`` with ``DJANGO_SETTINGS_MODULE``, or the @@ -92,6 +97,33 @@ example, the default settings don't define ``ROOT_URLCONF``, so Note that Django's default settings live in ``django/conf/global_settings.py``, if you're ever curious to see the full list of defaults. +dumpdata [appname appname ...] +------------------------------ + +**New in Django development version** + +Output to standard output all data in the database associated with the named +application(s). + +By default, the database will be dumped in JSON format. If you want the output +to be in another format, use the ``--format`` option (e.g., ``format=xml``). +You may specify any Django serialization backend (including any user specified +serialization backends named in the ``SERIALIZATION_MODULES`` setting). + +If no application name is provided, all installed applications will be dumped. + +The output of ``dumpdata`` can be used as input for ``loaddata``. + +flush +----- + +**New in Django development version** + +Return the database to the state it was in immediately after syncdb was +executed. This means that all data will be removed from the database, any +post-synchronization handlers will be re-executed, and the ``initial_data`` +fixture will be re-installed. + inspectdb --------- @@ -136,8 +168,92 @@ only works in PostgreSQL and with certain types of MySQL tables. install [appname appname ...] ----------------------------- +**Removed in Django development version** + Executes the equivalent of ``sqlall`` for the given appnames. +loaddata [fixture fixture ...] +------------------------------ + +**New in Django development version** + +Searches for and loads the contents of the named fixture into the database. + +A *Fixture* is a collection of files that contain the serialized contents of +the database. Each fixture has a unique name; however, the files that +comprise the fixture can be distributed over multiple directories, in +multiple applications. + +Django will search in three locations for fixtures: + + 1. In the ``fixtures`` directory of every installed application + 2. In any directory named in the ``FIXTURE_DIRS`` setting + 3. In the literal path named by the fixture + +Django will load any and all fixtures it finds in these locations that match +the provided fixture names. + +If the named fixture has a file extension, only fixtures of that type +will be loaded. For example:: + + django-admin.py loaddata mydata.json + +would only load JSON fixtures called ``mydata``. The fixture extension +must correspond to the registered name of a serializer (e.g., ``json`` or +``xml``). + +If you omit the extension, Django will search all available fixture types +for a matching fixture. For example:: + + django-admin.py loaddata mydata + +would look for any fixture of any fixture type called ``mydata``. If a fixture +directory contained ``mydata.json``, that fixture would be loaded +as a JSON fixture. However, if two fixtures with the same name but different +fixture type are discovered (for example, if ``mydata.json`` and +``mydata.xml`` were found in the same fixture directory), fixture +installation will be aborted, and any data installed in the call to +``loaddata`` will be removed from the database. + +The fixtures that are named can include directory components. These +directories will be inluded in the search path. For example:: + + django-admin.py loaddata foo/bar/mydata.json + +would search ``<appname>/fixtures/foo/bar/mydata.json`` for each installed +application, ``<dirname>/foo/bar/mydata.json`` for each directory in +``FIXTURE_DIRS``, and the literal path ``foo/bar/mydata.json``. + +Note that the order in which fixture files are processed is undefined. However, +all fixture data is installed as a single transaction, so data in +one fixture can reference data in another fixture. If the database backend +supports row-level constraints, these constraints will be checked at the +end of the transaction. + +.. admonition:: MySQL and Fixtures + + Unfortunately, MySQL isn't capable of completely supporting all the + features of Django fixtures. If you use MyISAM tables, MySQL doesn't + support transactions or constraints, so you won't get a rollback if + multiple transaction files are found, or validation of fixture data. + If you use InnoDB tables, you won't be able to have any forward + references in your data files - MySQL doesn't provide a mechanism to + defer checking of row constraints until a transaction is committed. + +reset [appname appname ...] +--------------------------- +Executes the equivalent of ``sqlreset`` for the given appnames. + +runfcgi [options] +----------------- +Starts a set of FastCGI processes suitable for use with any web server +which supports the FastCGI protocol. See the `FastCGI deployment +documentation`_ for details. Requires the Python FastCGI module from +`flup`_. + +.. _FastCGI deployment documentation: ../fastcgi/ +.. _flup: http://www.saddi.com/software/flup/ + runserver [optional port number, or ipaddr:port] ------------------------------------------------ @@ -231,15 +347,12 @@ sqlclear [appname appname ...] Prints the DROP TABLE SQL statements for the given appnames. -sqlindexes [appname appname ...] ----------------------------------------- - -Prints the CREATE INDEX SQL statements for the given appnames. +sqlcustom [appname appname ...] +------------------------------- -sqlinitialdata [appname appname ...] --------------------------------------------- +**New in Django development version** -Prints the initial INSERT SQL statements for the given appnames. +Prints the custom SQL statements for the given appnames. For each model in each specified app, this command looks for the file ``<appname>/sql/<modelname>.sql``, where ``<appname>`` is the given appname and @@ -250,11 +363,23 @@ command. Each of the SQL files, if given, is expected to contain valid SQL. The SQL files are piped directly into the database after all of the models' -table-creation statements have been executed. Use this SQL hook to populate -tables with any necessary initial records, SQL functions or test data. +table-creation statements have been executed. Use this SQL hook to make any +table modifications, or insert any SQL functions into the database. Note that the order in which the SQL files are processed is undefined. +sqlindexes [appname appname ...] +---------------------------------------- + +Prints the CREATE INDEX SQL statements for the given appnames. + +sqlinitialdata [appname appname ...] +-------------------------------------------- + +**Removed in Django development version** + +This method has been renamed ``sqlcustom`` in the development version of Django. + sqlreset [appname appname ...] -------------------------------------- @@ -294,6 +419,10 @@ this command to install the default apps. If you're installing the ``django.contrib.auth`` application, ``syncdb`` will give you the option of creating a superuser immediately. +``syncdb`` will also search for and install any fixture named ``initial_data``. +See the documentation for ``loaddata`` for details on the specification of +fixture data files. + test ---- @@ -343,12 +472,37 @@ setting the Python path for you. .. _import search path: http://diveintopython.org/getting_to_know_python/everything_is_an_object.html +--format +-------- + +**New in Django development version** + +Example usage:: + + django-admin.py dumpdata --format=xml + +Specifies the output format that will be used. The name provided must be the name +of a registered serializer. + --help ------ Displays a help message that includes a terse list of all available actions and options. +--indent +-------- + +**New in Django development version** + +Example usage:: + + django-admin.py dumpdata --indent=4 + +Specifies the number of spaces that will be used for indentation when +pretty-printing output. By default, output will *not* be pretty-printed. +Pretty-printing will only be enabled if the indent option is provided. + --noinput --------- diff --git a/docs/email.txt b/docs/email.txt index 1edce88cef..1f4ce4ef42 100644 --- a/docs/email.txt +++ b/docs/email.txt @@ -34,8 +34,8 @@ The simplest way to send e-mail is using the function ``django.core.mail.send_mail()``. Here's its definition:: send_mail(subject, message, from_email, recipient_list, - fail_silently=False, auth_user=EMAIL_HOST_USER, - auth_password=EMAIL_HOST_PASSWORD) + fail_silently=False, auth_user=None, + auth_password=None) The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters are required. @@ -65,7 +65,7 @@ send_mass_mail() Here's the definition:: send_mass_mail(datatuple, fail_silently=False, - auth_user=EMAIL_HOST_USER, auth_password=EMAIL_HOST_PASSWORD): + auth_user=None, auth_password=None): ``datatuple`` is a tuple in which each element is in this format:: diff --git a/docs/fastcgi.txt b/docs/fastcgi.txt index b61df49190..1efeaf09cf 100644 --- a/docs/fastcgi.txt +++ b/docs/fastcgi.txt @@ -274,7 +274,7 @@ In your Web root directory, add this to a file named ``.htaccess`` :: Then, create a small script that tells Apache how to spawn your FastCGI program. Create a file ``mysite.fcgi`` and place it in your Web directory, and -be sure to make it executable :: +be sure to make it executable:: #!/usr/bin/python import sys, os diff --git a/docs/forms.txt b/docs/forms.txt index 3fa11fea64..8c40eeb997 100644 --- a/docs/forms.txt +++ b/docs/forms.txt @@ -173,10 +173,10 @@ creation view that takes validation into account:: # Check for validation errors errors = manipulator.get_validation_errors(new_data) + manipulator.do_html2python(new_data) if errors: return render_to_response('places/errors.html', {'errors': errors}) else: - manipulator.do_html2python(new_data) new_place = manipulator.save(new_data) return HttpResponse("Place created: %s" % new_place) @@ -229,10 +229,10 @@ Below is the finished view:: # Check for errors. errors = manipulator.get_validation_errors(new_data) + manipulator.do_html2python(new_data) if not errors: # No errors. This means we can save the data! - manipulator.do_html2python(new_data) new_place = manipulator.save(new_data) # Redirect to the object's "edit" page. Always use a redirect @@ -324,8 +324,8 @@ about editing an existing one? It's shockingly similar to creating a new one:: if request.method == 'POST': new_data = request.POST.copy() errors = manipulator.get_validation_errors(new_data) + manipulator.do_html2python(new_data) if not errors: - manipulator.do_html2python(new_data) manipulator.save(new_data) # Do a post-after-redirect so that reload works, etc. @@ -406,8 +406,8 @@ Here's a simple function that might drive the above form:: if request.method == 'POST': new_data = request.POST.copy() errors = manipulator.get_validation_errors(new_data) + manipulator.do_html2python(new_data) if not errors: - manipulator.do_html2python(new_data) # Send e-mail using new_data here... @@ -608,6 +608,10 @@ fails. If no message is passed in, a default message is used. order). If the given field does (or does not have, in the latter case) the given value, then the current field being validated is required. + An optional ``other_label`` argument can be passed which, if given, is used + in error messages instead of the value. This allows more user friendly error + messages if the value itself is not descriptive enough. + Note that because validators are called before any ``do_html2python()`` functions, the value being compared against is a string. So ``RequiredIfOtherFieldEquals('choice', '1')`` is correct, whilst diff --git a/docs/generic_views.txt b/docs/generic_views.txt index 23f40acb24..a136c72a07 100644 --- a/docs/generic_views.txt +++ b/docs/generic_views.txt @@ -686,7 +686,7 @@ 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 zero-indexed 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. @@ -752,6 +752,12 @@ If the results are paginated, the context will contain these extra variables: * ``previous``: The previous page number, as an integer. This is 1-based. + * `last_on_page`: **New in Django development version** The number of the + last result on the current page. This is 1-based. + + * `first_on_page`: **New in Django development version** The number of the + first result on the current page. This is 1-based. + * ``pages``: The total number of pages, as an integer. * ``hits``: The total number of objects across *all* pages, not just this diff --git a/docs/install.txt b/docs/install.txt index 89a1415f5a..3eede02af0 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -51,16 +51,20 @@ make sure a database server is running. Django works with PostgreSQL_ Additionally, you'll need to make sure your Python database bindings are installed. -* If you're using PostgreSQL, you'll need the psycopg_ package (version 1.1 -- - not version 1.0 or version 2, which is still in beta). If you're on Windows, - check out the unofficial `compiled Windows version`_. -* If you're using MySQL, you'll need MySQLdb_. +* If you're using PostgreSQL, you'll need the psycopg_ package (version 2 is + recommended with ``postgresql_psycopg2`` backend, version 1.1 works also with the + ``postgresql``` backend). + + If you're on Windows, check out the unofficial `compiled Windows version`_. + +* If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher. + * If you're using SQLite, you'll need pysqlite_. Use version 2.0.3 or higher. .. _PostgreSQL: http://www.postgresql.org/ .. _MySQL: http://www.mysql.com/ .. _Django's ticket system: http://code.djangoproject.com/report/1 -.. _psycopg: http://initd.org/projects/psycopg1 +.. _psycopg: http://initd.org/tracker/psycopg .. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/ .. _MySQLdb: http://sourceforge.net/projects/mysql-python .. _SQLite: http://www.sqlite.org/ @@ -77,10 +81,18 @@ It's easy either way. Installing the official version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -1. Download Django-0.95.tar.gz from our `download page`_. -2. ``tar xzvf Django-0.95.tar.gz`` -3. ``cd Django-0.95`` -4. ``sudo python setup.py install`` + 1. Check the `distribution specific notes`_ to see if your + platform/distribution provides official Django packages/installers. + Distribution-provided packages will typically allow for automatic + installation of dependancies and easy upgrade paths. + + 2. Download Django-0.95.tar.gz from our `download page`_. + + 3. ``tar xzvf Django-0.95.tar.gz`` + + 4. ``cd Django-0.95`` + + 5. ``sudo python setup.py install`` Note that the last command will automatically download and install setuptools_ if you don't already have it installed. This requires a working Internet @@ -93,6 +105,7 @@ The command will install Django in your Python installation's ``site-packages`` directory. .. _setuptools: http://peak.telecommunity.com/DevCenter/setuptools +.. _distribution specific notes: ../distributions/ Installing the development version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/model-api.txt b/docs/model-api.txt index 8abd88f7ec..e66e96de68 100644 --- a/docs/model-api.txt +++ b/docs/model-api.txt @@ -498,6 +498,12 @@ or outside your model class altogether:: class Foo(models.Model): gender = models.CharField(maxlength=1, choices=GENDER_CHOICES) +For each model field that has ``choices`` set, Django will add a method to +retrieve the human-readable name for the field's current value. See +`get_FOO_display`_ in the database API documentation. + +.. _get_FOO_display: ../db_api/#get-foo-display + Finally, note that choices can be any iterable object -- not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking ``choices`` to be dynamic, you're probably better off using @@ -874,8 +880,8 @@ the relationship should work. All are optional: force Django to add the descriptor for the reverse relationship, allowing ``ManyToMany`` relationships to be non-symmetrical. - - ``db_table`` The name of the table to create for storing the many-to-many + + ``db_table`` The name of the table to create for storing the many-to-many data. If this is not provided, Django will assume a default name based upon the names of the two tables being joined. @@ -1210,6 +1216,9 @@ screen via ``<script src="">`` tags. This can be used to tweak a given type of admin page in JavaScript or to provide "quick links" to fill in default values for certain fields. +If relative URLs are used, Django admin will automatically prepend these links +with ``settings.ADMIN_MEDIA_PREFIX``. + ``list_display`` ---------------- @@ -1272,8 +1281,8 @@ A few special cases to note about ``list_display``: return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name) colored_name.allow_tags = True - * If the string given is a method of the model that returns True or False - Django will display a pretty "on" or "off" icon if you give the method a + * If the string given is a method of the model that returns True or False + Django will display a pretty "on" or "off" icon if you give the method a ``boolean`` attribute whose value is ``True``. Here's a full example model:: @@ -1295,10 +1304,30 @@ A few special cases to note about ``list_display``: list_display = ('__str__', 'some_other_field') - * For any element of ``list_display`` that is not a field on the model, the - change list page will not allow ordering by that column. This is because - ordering is done at the database level, and Django has no way of knowing - how to order the result of a custom method at the SQL level. + * Usually, elements of ``list_display`` that aren't actual database fields + can't be used in sorting (because Django does all the sorting at the + database level). + + However, if an element of ``list_display`` represents a certain database + field, you can indicate this fact by setting the ``admin_order_field`` + attribute of the item. + + For example:: + + class Person(models.Model): + first_name = models.CharField(maxlength=50) + color_code = models.CharField(maxlength=6) + + class Admin: + list_display = ('first_name', 'colored_first_name') + + def colored_first_name(self): + return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name) + colored_first_name.allow_tags = True + colored_first_name.admin_order_field = 'first_name' + + The above will tell Django to order by the ``first_name`` field when + trying to sort by ``colored_first_name`` in the admin. ``list_display_links`` ---------------------- @@ -1412,7 +1441,7 @@ This should be set to a list of field names that will be searched whenever somebody submits a search query in that text box. These fields should be some kind of text field, such as ``CharField`` or -``TextField``. You can also perform a related lookup on a ``ForeignKey`` with +``TextField``. You can also perform a related lookup on a ``ForeignKey`` with the lookup API "follow" notation:: search_fields = ['foreign_key__related_fieldname'] @@ -1721,11 +1750,29 @@ But this template code is good:: <a href="{{ object.get_absolute_url }}">{{ object.name }}</a> -(Yes, we know ``get_absolute_url()`` couples URLs to models, which violates the -DRY principle, because URLs are defined both in a URLconf and in the model. -This is a rare case in which we've intentionally violated that principle for -the sake of convenience. With that said, we're working on an even cleaner way -of specifying URLs in a more DRY fashion.) +The ``permalink`` decorator +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**New in Django development version.** + +The problem with the way we wrote ``get_absolute_url()`` above is that it +slightly violates the DRY principle: the URL for this object is defined both +in the URLConf file and in the model. + +You can further decouple your models from the URLconf using the ``permalink`` +decorator. This decorator is passed the view function and any parameters you +would use for accessing this instance directly. Django then works out the +correct full URL path using the URLconf. For example:: + + from django.db.models import permalink + + def get_absolute_url(self): + return ('people.views.details', str(self.id)) + get_absolute_url = permalink(get_absolute_url) + +In this way, you're tying the model's absolute URL to the view that is used +to display it, without repeating the URL information anywhere. You can still +use the ``get_absolute_url`` method in templates, as before. Executing custom SQL -------------------- diff --git a/docs/newforms.txt b/docs/newforms.txt index 063f686ed5..33aaf14357 100644 --- a/docs/newforms.txt +++ b/docs/newforms.txt @@ -51,9 +51,10 @@ too messy. The choice is yours. Overview ======== -As with the ``django.forms`` ("manipulators") system before it, ``django.newforms`` -is intended to handle HTML form display, validation and redisplay. It's what -you use if you want to perform server-side validation for an HTML form. +As with the ``django.forms`` ("manipulators") system before it, +``django.newforms`` is intended to handle HTML form display, data processing +(validation) and redisplay. It's what you use if you want to perform +server-side validation for an HTML form. For example, if your Web site has a contact form that visitors can use to send you e-mail, you'd use this library to implement the display of the HTML @@ -571,6 +572,46 @@ is a list-like object that is displayed as an HTML ``<ul>`` when printed:: >>> str(f['subject'].errors) '' +Subclassing forms +----------------- + +If you subclass a custom ``Form`` class, the resulting ``Form`` class will +include all fields of the parent class(es), followed by the fields you define +in the subclass. + +In this example, ``ContactFormWithPriority`` contains all the fields from +``ContactForm``, plus an additional field, ``priority``. The ``ContactForm`` +fields are ordered first:: + + >>> class ContactFormWithPriority(ContactForm): + ... priority = forms.CharField() + >>> f = ContactFormWithPriority(auto_id=False) + >>> print f.as_ul() + <li>Subject: <input type="text" name="subject" maxlength="100" /></li> + <li>Message: <input type="text" name="message" /></li> + <li>Sender: <input type="text" name="sender" /></li> + <li>Cc myself: <input type="checkbox" name="cc_myself" /></li> + <li>Priority: <input type="text" name="priority" /></li> + +It's possible to subclass multiple forms, treating forms as "mix-ins." In this +example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm`` +(in that order), and its field list includes the fields from the parent +classes:: + + >>> class PersonForm(Form): + ... first_name = CharField() + ... last_name = CharField() + >>> class InstrumentForm(Form): + ... instrument = CharField() + >>> class BeatleForm(PersonForm, InstrumentForm): + ... haircut_type = CharField() + >>> b = BeatleForm(auto_id=False) + >>> print b.as_ul() + <li>First name: <input type="text" name="first_name" /></li> + <li>Last name: <input type="text" name="last_name" /></li> + <li>Instrument: <input type="text" name="instrument" /></li> + <li>Haircut type: <input type="text" name="haircut_type" /></li> + Fields ====== diff --git a/docs/outputting_pdf.txt b/docs/outputting_pdf.txt index 464bf7fcb8..bd6ae7a660 100644 --- a/docs/outputting_pdf.txt +++ b/docs/outputting_pdf.txt @@ -29,7 +29,7 @@ Test your installation by importing it in the Python interactive interpreter:: If that command doesn't raise any errors, the installation worked. -.. _user guide: http://www.reportlab.org/rsrc/userguide.pdf +.. _user guide: http://www.reportlab.com/docs/userguide.pdf Write your view =============== diff --git a/docs/request_response.txt b/docs/request_response.txt index afea0bcd53..6dfe78a686 100644 --- a/docs/request_response.txt +++ b/docs/request_response.txt @@ -432,3 +432,118 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in ``HttpResponseServerError`` Acts just like ``HttpResponse`` but uses a 500 status code. + +Returning errors +================ + +Returning HTTP error codes in Django is easy. We've already mentioned the +``HttpResponseNotFound``, ``HttpResponseForbidden``, +``HttpResponseServerError``, etc., subclasses; just return an instance of one +of those subclasses instead of a normal ``HttpResponse`` in order to signify +an error. For example:: + + def my_view(request): + # ... + if foo: + return HttpResponseNotFound('<h1>Page not found</h1>') + else: + return HttpResponse('<h1>Page was found</h1>') + +Because 404 errors are by far the most common HTTP error, there's an easier way +to handle those errors. + +The Http404 exception +--------------------- + +When you return an error such as ``HttpResponseNotFound``, you're responsible +for defining the HTML of the resulting error page:: + + return HttpResponseNotFound('<h1>Page not found</h1>') + +For convenience, and because it's a good idea to have a consistent 404 error page +across your site, Django provides an ``Http404`` exception. If you raise +``Http404`` at any point in a view function, Django will catch it and return the +standard error page for your application, along with an HTTP error code 404. + +Example usage:: + + from django.http import Http404 + + def detail(request, poll_id): + try: + p = Poll.objects.get(pk=poll_id) + except Poll.DoesNotExist: + raise Http404 + return render_to_response('polls/detail.html', {'poll': p}) + +In order to use the ``Http404`` exception to its fullest, you should create a +template that is displayed when a 404 error is raised. This template should be +called ``404.html`` and located in the top level of your template tree. + +Customing error views +--------------------- + +The 404 (page not found) view +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When you raise an ``Http404`` exception, Django loads a special view devoted +to handling 404 errors. By default, it's the view +``django.views.defaults.page_not_found``, which loads and renders the template +``404.html``. + +This means you need to define a ``404.html`` template in your root template +directory. This template will be used for all 404 errors. + +This ``page_not_found`` view should suffice for 99% of Web applications, but if +you want to override the 404 view, you can specify ``handler404`` in your +URLconf, like so:: + + handler404 = 'mysite.views.my_custom_404_view' + +Behind the scenes, Django determines the 404 view by looking for ``handler404``. +By default, URLconfs contain the following line:: + + from django.conf.urls.defaults import * + +That takes care of setting ``handler404`` in the current module. As you can see +in ``django/conf/urls/defaults.py``, ``handler404`` is set to +``'django.views.defaults.page_not_found'`` by default. + +Three things to note about 404 views: + + * The 404 view is also called if Django doesn't find a match after checking + every regular expression in the URLconf. + + * If you don't define your own 404 view -- and simply use the default, + which is recommended -- you still have one obligation: To create a + ``404.html`` template in the root of your template directory. The default + 404 view will use that template for all 404 errors. + + * If ``DEBUG`` is set to ``True`` (in your settings module) then your 404 + view will never be used, and the traceback will be displayed instead. + +The 500 (server error) view +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Similarly, Django executes special-case behavior in the case of runtime errors +in view code. If a view results in an exception, Django will, by default, call +the view ``django.views.defaults.server_error``, which loads and renders the +template ``500.html``. + +This means you need to define a ``500.html`` template in your root template +directory. This template will be used for all server errors. + +This ``server_error`` view should suffice for 99% of Web applications, but if +you want to override the view, you can specify ``handler500`` in your +URLconf, like so:: + + handler500 = 'mysite.views.my_custom_error_view' + +Behind the scenes, Django determines the error view by looking for ``handler500``. +By default, URLconfs contain the following line:: + + from django.conf.urls.defaults import * + +That takes care of setting ``handler500`` in the current module. As you can see +in ``django/conf/urls/defaults.py``, ``handler500`` is set to +``'django.views.defaults.server_error'`` by default. diff --git a/docs/settings.txt b/docs/settings.txt index cdf440ed6b..b41281ee49 100644 --- a/docs/settings.txt +++ b/docs/settings.txt @@ -162,10 +162,13 @@ a model object and return its URL. This is a way of overriding ``get_absolute_url()`` methods on a per-installation basis. Example:: ABSOLUTE_URL_OVERRIDES = { - 'blogs.Weblog': lambda o: "/blogs/%s/" % o.slug, - 'news.Story': lambda o: "/stories/%s/%s/" % (o.pub_year, o.slug), + 'blogs.weblog': lambda o: "/blogs/%s/" % o.slug, + 'news.story': lambda o: "/stories/%s/%s/" % (o.pub_year, o.slug), } +Note that the model name used in this setting should be all lower-case, regardless +of the case of the actual model class name. + ADMIN_FOR --------- @@ -197,6 +200,9 @@ of (Full name, e-mail address). Example:: (('John', 'john@example.com'), ('Mary', 'mary@example.com')) +Note that Django will e-mail *all* of these people whenever an error happens. See the +section on `error reporting via e-mail`_ for more information. + ALLOWED_INCLUDE_ROOTS --------------------- @@ -236,10 +242,10 @@ The cache key prefix that the cache middleware should use. See the DATABASE_ENGINE --------------- -Default: ``'postgresql'`` +Default: ``''`` (Empty string) -Which database backend to use. Either ``'postgresql'``, ``'mysql'``, -``'sqlite3'`` or ``'ado_mssql'``. +Which database backend to use. Either ``'postgresql_psycopg2'``, +``'postgresql'``, ``'mysql'``, ``'sqlite3'`` or ``'ado_mssql'``. DATABASE_HOST ------------- @@ -328,6 +334,16 @@ 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 +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 +are inapporpriate for public consumption. File paths, configuration options, and +the like all give attackers extra information about your server. Never deploy a +site with ``DEBUG`` turned on. + DEFAULT_CHARSET --------------- @@ -409,12 +425,25 @@ Subject-line prefix for e-mail messages sent with ``django.core.mail.mail_admins or ``django.core.mail.mail_managers``. You'll probably want to include the trailing space. +FIXTURE_DIRS +------------- + +**New in Django development version** + +Default: ``()`` (Empty tuple) + +List of locations of the fixture data files, in search order. Note that +these paths should use Unix-style forward slashes, even on Windows. See +`Testing Django Applications`_. + +.. _Testing Django Applications: ../testing/ + IGNORABLE_404_ENDS ------------------ Default: ``('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', 'favicon.ico', '.php')`` -See also ``IGNORABLE_404_STARTS``. +See also ``IGNORABLE_404_STARTS`` and ``Error reporting via e-mail``. IGNORABLE_404_STARTS -------------------- @@ -422,7 +451,8 @@ IGNORABLE_404_STARTS Default: ``('/cgi-bin/', '/_vti_bin', '/_vti_inf')`` A tuple of strings that specify beginnings of URLs that should be ignored by -the 404 e-mailer. See ``SEND_BROKEN_LINK_EMAILS`` and ``IGNORABLE_404_ENDS``. +the 404 e-mailer. See ``SEND_BROKEN_LINK_EMAILS``, ``IGNORABLE_404_ENDS`` and +the section on `error reporting via e-mail`_. INSTALLED_APPS -------------- @@ -636,8 +666,19 @@ Default: ``False`` Whether to send an e-mail to the ``MANAGERS`` each time somebody visits a Django-powered page that is 404ed with a non-empty referer (i.e., a broken link). This is only used if ``CommonMiddleware`` is installed (see the -`middleware docs`_). See also ``IGNORABLE_404_STARTS`` and -``IGNORABLE_404_ENDS``. +`middleware docs`_). See also ``IGNORABLE_404_STARTS``, +``IGNORABLE_404_ENDS`` and the section on `error reporting via e-mail`_ + +SERIALIZATION_MODULES +--------------------- + +Default: Not defined. + +A dictionary of modules containing serializer definitions (provided as +strings), keyed by a string identifier for that serialization type. For +example, to define a YAML serializer, use:: + + SERIALIZATION_MODULES = { 'yaml' : 'path.to.yaml_serializer' } SERVER_EMAIL ------------ @@ -827,6 +868,11 @@ manual configuration option (see below), Django will *not* touch the ``TZ`` environment variable, and it'll be up to you to ensure your processes are running in the correct environment. +.. note:: + Django cannot reliably use alternate time zones in a Windows environment. + If you're running Django on Windows, this variable must be set to match the + system timezone. + URL_VALIDATOR_USER_AGENT ------------------------ @@ -972,3 +1018,36 @@ Also, it's an error to call ``configure()`` more than once, or to call It boils down to this: Use exactly one of either ``configure()`` or ``DJANGO_SETTINGS_MODULE``. Not both, and not neither. + +Error reporting via e-mail +========================== + +Server errors +------------- + +When ``DEBUG`` is ``False``, Django will e-mail the users listed in the +``ADMIN`` setting whenever your code raises an unhandled exception and results +in an internal server error (HTTP status code 500). This gives the +administrators immediate notification of any errors. + +To disable this behavior, just remove all entries from the ``ADMINS`` setting. + +404 errors +---------- + +When ``DEBUG`` is ``False`` and your ``MIDDLEWARE_CLASSES`` setting includes +``CommonMiddleware``, Django will e-mail the users listed in the ``MANAGERS`` +setting whenever your code raises a 404 and the request has a referer. +(It doesn't bother to e-mail for 404s that don't have a referer.) + +You can tell Django to stop reporting particular 404s by tweaking the +``IGNORABLE_404_ENDS`` and ``IGNORABLE_404_STARTS`` settings. Both should be a +tuple of strings. For example:: + + IGNORABLE_404_ENDS = ('.php', '.cgi') + IGNORABLE_404_STARTS = ('/phpmyadmin/') + +In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not* +be reported. Neither will any URL starting with ``/phpmyadmin/``. + +To disable this behavior, just remove all entries from the ``MANAGERS`` setting. diff --git a/docs/syndication_feeds.txt b/docs/syndication_feeds.txt index 72b05ff16a..a64914de3f 100644 --- a/docs/syndication_feeds.txt +++ b/docs/syndication_feeds.txt @@ -127,7 +127,7 @@ put into those elements. it two template context variables: * ``{{ obj }}`` -- The current object (one of whichever objects you - returned in ``items()``). + returned in ``items()``). * ``{{ site }}`` -- A ``django.models.core.sites.Site`` object representing the current site. This is useful for ``{{ site.domain }}`` or ``{{ site.name }}``. @@ -478,6 +478,22 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas categories = ("python", "django") # Hard-coded list of categories. + # COPYRIGHT NOTICE -- One of the following three is optional. The + # framework looks for them in this order. + + def copyright(self, obj): + """ + Takes the object returned by get_object() and returns the feed's + copyright notice as a normal Python string. + """ + + def copyright(self): + """ + Returns the feed's copyright notice as a normal Python string. + """ + + copyright = 'Copyright (c) 2007, Sally Smith' # Hard-coded copyright notice. + # ITEMS -- One of the following three is required. The framework looks # for them in this order. @@ -659,6 +675,23 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas item_categories = ("python", "django") # Hard-coded categories. + # ITEM COPYRIGHT NOTICE (only applicable to Atom feeds) -- One of the + # following three is optional. The framework looks for them in this + # order. + + def item_copyright(self, obj): + """ + Takes an item, as returned by items(), and returns the item's + copyright notice as a normal Python string. + """ + + def item_copyright(self): + """ + Returns the copyright notice for every item in the feed. + """ + + item_copyright = 'Copyright (c) 2007, Sally Smith' # Hard-coded copyright notice. + The low-level framework ======================= diff --git a/docs/templates.txt b/docs/templates.txt index 9f8fe446b4..d53270ac16 100644 --- a/docs/templates.txt +++ b/docs/templates.txt @@ -253,6 +253,16 @@ Here are some tips for working with inheritance: if you want to add to the contents of a parent block instead of completely overriding it. + * **New in Django development version:** For extra readability, you can + optionally give a *name* to your ``{% endblock %}`` tag. For example:: + + {% block content %} + ... + {% endblock content %} + + In larger templates, this technique helps you see which ``{% block %}`` + tags are being closed. + Finally, note that you can't define multiple ``{% block %}`` tags with the same name in the same template. This limitation exists because a block tag works in "both" directions. That is, a block tag doesn't just provide a hole to fill -- @@ -635,6 +645,7 @@ Available format strings: output, because this includes periods to match Associated Press style.) A ``'AM'`` or ``'PM'``. ``'AM'`` + b Month, textual, 3 letters, lowercase. ``'jan'`` B Not implemented. d Day of the month, 2 digits with ``'01'`` to ``'31'`` leading zeros. @@ -819,6 +830,40 @@ The argument tells which template bit to output: Note: ``opencomment`` and ``closecomment`` are new in the Django development version. +url +~~~ + +**New in Django development version** + +**Note that the syntax for this tag may change in the future, as we make it more robust.** + +Returns an absolute URL (i.e., a URL without the domain name) matching a given +view function and optional parameters. This is a way to output links without +violating the DRY principle by having to hard-code URLs in your templates:: + + {% url path.to.some_view arg1,arg2,name1=value1 %} + +The first argument is a path to a view function in the format +``package.package.module.function``. Additional arguments are optional and +should be comma-separated values that will be used as positional and keyword +arguments in the URL. All arguments required by the URLconf should be present. + +For example, suppose you have a view, ``app_name.client``, whose URLconf takes +a client ID. The URLconf line might look like this:: + + ('^client/(\d+)/$', 'app_name.client') + +If this app's URLconf is included into the project's URLconf under a path +such as this:: + + ('^clients/', include('project_name.app_name.urls')) + +...then, in a template, you can create a link to this view like this:: + + {% url app_name.client client.id %} + +The template tag will output the string ``/clients/client/123/``. + widthratio ~~~~~~~~~~ @@ -1133,6 +1178,16 @@ Truncates a string after a certain number of words. **Argument:** Number of words to truncate after +truncatewords_html +~~~~~~~~~~~~~~~~~~ + +Similar to ``truncatewords``, except that it is aware of HTML tags. Any tags +that are opened in the string and not closed before the truncation point, are +closed immediately after the truncation. + +This is less efficient than ``truncatewords``, so should only be used when it +is being passed HTML text. + unordered_list ~~~~~~~~~~~~~~ diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 5f9c5bde43..5dd8e4fde0 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -654,6 +654,18 @@ decorator instead:: 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 import template + + @template.stringfilter + def lower(value): + return value.lower() + Writing custom template tags ---------------------------- @@ -801,6 +813,70 @@ Python 2.4 and above:: If you leave off the ``name`` argument, as in the second example above, Django will use the function's name as the tag name. +Passing template variables to the tag +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Although you can pass any number of arguments to a template tag using +``token.split_contents()``, the arguments are all unpacked as +string literals. A little more work is required in order to dynamic content (a +template variable) to a template tag as an argument. + +While the previous examples have formatted the current time into a string and +returned the string, suppose you wanted to pass in a ``DateTimeField`` from an +object and have the template tag format that date-time:: + + <p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p> + +Initially, ``token.split_contents()`` will return three values: + + 1. The tag name ``format_time``. + 2. The string "blog_entry.date_updated" (without the surrounding quotes). + 3. The formatting string "%Y-%m-%d %I:%M %p". The return value from + ``split_contents()`` will include the leading and trailing quotes for + string literals like this. + +Now your tag should begin to look like this:: + + from django import template + def do_format_time(parser, token): + try: + # split_contents() knows not to split quoted strings. + tag_name, date_to_be_formatted, format_string = token.split_contents() + except ValueError: + raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents[0] + if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")): + raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name + return FormatTimeNode(date_to_be_formatted, format_string[1:-1]) + +You also have to change the renderer to retrieve the actual contents of the +``date_updated`` property of the ``blog_entry`` object. This can be +accomplished by using the ``resolve_variable()`` function in +``django.template``. You pass ``resolve_variable()`` the variable name and the +current context, available in the ``render`` method:: + + from django import template + from django.template import resolve_variable + import datetime + class FormatTimeNode(template.Node): + def __init__(self, date_to_be_formatted, format_string): + self.date_to_be_formatted = date_to_be_formatted + self.format_string = format_string + + def render(self, context): + try: + actual_date = resolve_variable(self.date_to_be_formatted, context) + return actual_date.strftime(self.format_string) + except VariableDoesNotExist: + return '' + +``resolve_variable`` will try to resolve ``blog_entry.date_updated`` and then +format it accordingly. + +.. note:: + The ``resolve_variable()`` function will throw a ``VariableDoesNotExist`` + exception if it cannot resolve the string passed to it in the current + context of the page. + Shortcut for simple tags ~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/testing.txt b/docs/testing.txt index e7c1a3b161..f7fd402502 100644 --- a/docs/testing.txt +++ b/docs/testing.txt @@ -92,7 +92,7 @@ Writing unittests Like doctests, Django's unit tests use a standard library module: unittest_. As with doctests, Django's test runner looks for any unit test cases defined -in ``models.py``, or in a ``tests.py`` file stored in the application +in ``models.py``, or in a ``tests.py`` file stored in the application directory. An equivalent unittest test case for the above example would look like:: @@ -111,8 +111,8 @@ An equivalent unittest test case for the above example would look like:: self.assertEquals(self.cat.speak(), 'The cat says "meow"') When you `run your tests`_, the test utility will find all the test cases -(that is, subclasses of ``unittest.TestCase``) in ``models.py`` and -``tests.py``, automatically build a test suite out of those test cases, +(that is, subclasses of ``unittest.TestCase``) in ``models.py`` and +``tests.py``, automatically build a test suite out of those test cases, and run that suite. For more details about ``unittest``, see the `standard library unittest @@ -164,12 +164,12 @@ in different circumstances. Testing Tools ============= -To assist in testing various features of your application, Django provides +To assist in testing various features of your application, Django provides tools that can be used to establish tests and test conditions. * `Test Client`_ * Fixtures_ - + Test Client ----------- @@ -178,36 +178,30 @@ GET and POST requests on a URL, and observe the response that is received. This allows you to test that the correct view is executed for a given URL, and that the view constructs the correct response. -As the response is generated, the Test Client gathers details on the +As the response is generated, the Test Client gathers details on the Template and Context objects that were used to generate the response. These Templates and Contexts are then provided as part of the response, and can be used as test conditions. .. admonition:: Test Client vs Browser Automation? - The Test Client is not intended as a replacement for Twill_, Selenium_, - or other browser automation frameworks - it is intended to allow - testing of the contexts and templates produced by a view, + The Test Client is not intended as a replacement for Twill_, Selenium_, + or other browser automation frameworks - it is intended to allow + testing of the contexts and templates produced by a view, rather than the HTML rendered to the end-user. - + A comprehensive test suite should use a combination of both: Test Client - tests to establish that the correct view is being called and that + tests to establish that the correct view is being called and that the view is collecting the correct context data, and Browser Automation tests to check that user interface behaves as expected. - + .. _Twill: http://twill.idyll.org/ .. _Selenium: http://www.openqa.org/selenium/ -The Test Client is stateful; if a cookie is returned as part of a response, -that cookie is provided as part of the next request issued to that Client -instance. Expiry policies for these cookies are not followed; if you want -a cookie to expire, either delete it manually from ``client.cookies``, or -create a new Client instance (which will effectively delete all cookies). - Making requests ~~~~~~~~~~~~~~~ -Creating an instance of ``Client`` (``django.test.client.Client``) requires +Creating an instance of ``Client`` (``django.test.client.Client``) requires no arguments at time of construction. Once constructed, the following methods can be invoked on the ``Client`` instance. @@ -222,23 +216,29 @@ can be invoked on the ``Client`` instance. http://yoursite.com/customers/details/?name=fred&age=7 -``post(path, data={})`` - Make a POST request on the provided ``path``. The key-value pairs in the - data dictionary will be used to create the POST data payload. This payload - will be transmitted with the mimetype ``multipart/form-data``. - - However submitting files is a special case. To POST a file, you need only - provide the file field name as a key, and a file handle to the file you wish to - upload as a value. The Test Client will populate the two POST fields (i.e., - ``field`` and ``field_file``) required by FileField. For example:: +``post(path, data={}, content_type=MULTIPART_CONTENT)`` + Make a POST request on the provided ``path``. If you provide a content type + (e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be + sent as-is in the POST request, using the content type in the HTTP + ``Content-Type`` header. + + If you do not provide a value for ``content_type``, the values in + ``data`` will be transmitted with a content type of ``multipart/form-data``. + The key-value pairs in the data dictionary will be encoded as a multipart + message and used to create the POST data payload. + + Submitting files is a special case. To POST a file, you need only + provide the file field name as a key, and a file handle to the file you wish to + upload as a value. The Test Client will populate the two POST fields (i.e., + ``field`` and ``field_file``) required by Django's FileField. For example:: c = Client() f = open('wishlist.doc') c.post('/customers/wishes/', {'name':'fred', 'attachment':f}) f.close() - will result in the evaluation of a POST request on ``/customers/wishes/``, - with a POST dictionary that contains `name`, `attachment` (containing the + will result in the evaluation of a POST request on ``/customers/wishes/``, + with a POST dictionary that contains `name`, `attachment` (containing the file name), and `attachment_file` (containing the file data). Note that you need to manually close the file after it has been provided to the POST. @@ -250,65 +250,104 @@ can be invoked on the ``Client`` instance. call to ``login()`` stimulates the series of GET and POST calls required to log a user into a @login_required protected view. - If login is possible, the final return value of ``login()`` is the response + If login is possible, the final return value of ``login()`` is the response that is generated by issuing a GET request on the protected URL. If login is not possible, ``login()`` returns False. - Note that since the test suite will be executed using the test database, + Note that since the test suite will be executed using the test database, which contains no users by default. As a result, logins for your production - site will not work. You will need to create users as part of the test suite - to be able to test logins to your application. + site will not work. You will need to create users as part of the test suite + to be able to test logins to your application. Testing Responses ~~~~~~~~~~~~~~~~~ -The ``get()``, ``post()`` and ``login()`` methods all return a Response -object. This Response object has the following properties that can be used +The ``get()``, ``post()`` and ``login()`` methods all return a Response +object. This Response object has the following properties that can be used for testing purposes: =============== ========================================================== Property Description =============== ========================================================== - ``status_code`` The HTTP status of the response. See RFC2616_ for a + ``status_code`` The HTTP status of the response. See RFC2616_ for a full list of HTTP status codes. - ``content`` The body of the response. The is the final page - content as rendered by the view, or any error message + ``content`` The body of the response. The is the final page + content as rendered by the view, or any error message (such as the URL for a 302 redirect). - ``template`` The Template instance that was used to render the final - content. Testing ``template.name`` can be particularly - useful; if the template was loaded from a file, - ``template.name`` will be the file name that was loaded. + ``template`` The Template instance that was used to render the final + content. Testing ``template.name`` can be particularly + useful; if the template was loaded from a file, + ``template.name`` will be the file name that was loaded. - If multiple templates were rendered, (e.g., if one - template includes another template),``template`` will - be a list of Template objects, in the order in which + If multiple templates were rendered, (e.g., if one + template includes another template),``template`` will + be a list of Template objects, in the order in which they were rendered. - ``context`` The Context that was used to render the template that + ``context`` The Context that was used to render the template that produced the response content. - As with ``template``, if multiple templates were rendered - ``context`` will be a list of Context objects, stored in - the order in which they were rendered. + As with ``template``, if multiple templates were rendered + ``context`` will be a list of Context objects, stored in + the order in which they were rendered. =============== ========================================================== .. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html +Exceptions +~~~~~~~~~~ + +If you point the Test Client at a view that raises an exception, that exception +will be visible in the test case. You can then use a standard ``try...catch`` +block, or ``unittest.TestCase.assertRaises()`` to test for exceptions. + +The only exceptions that are not visible in a Test Case are ``Http404``, +``PermissionDenied`` and ``SystemExit``. Django catches these exceptions +internally and converts them into the appropriate HTTP responses codes. + +Persistent state +~~~~~~~~~~~~~~~~ + +The Test Client is stateful; if a cookie is returned as part of a response, +that cookie is provided as part of the next request issued by that Client +instance. Expiry policies for these cookies are not followed; if you want +a cookie to expire, either delete it manually or create a new Client +instance (which will effectively delete all cookies). + +There are two properties of the Test Client which are used to store persistent +state information. If necessary, these properties can be interrogated as +part of a test condition. + + =============== ========================================================== + Property Description + =============== ========================================================== + ``cookies`` A Python ``SimpleCookie`` object, containing the current + values of all the client cookies. + + ``session`` A dictionary-like object containing session information. + See the `session documentation`_ for full details. + =============== ========================================================== + +.. _`session documentation`: ../sessions/ + +Example +~~~~~~~ + The following is a simple unit test using the Test Client:: - + import unittest from django.test.client import Client - + class SimpleTest(unittest.TestCase): def setUp(self): # Every test needs a client self.client = Client() - def test_details(self): + def test_details(self): # Issue a GET request response = self.client.get('/customer/details/') - + # Check that the respose is 200 OK self.failUnlessEqual(response.status_code, 200) # Check that the rendered context contains 5 customers @@ -317,7 +356,55 @@ The following is a simple unit test using the Test Client:: Fixtures -------- -Feature still to come... +A test case for a database-backed website isn't much use if there isn't any +data in the database. To make it easy to put test data into the database, +Django provides a fixtures framework. + +A *Fixture* is a collection of files that contain the serialized contents of +the database. Each fixture has a unique name; however, the files that +comprise the fixture can be distributed over multiple directories, in +multiple applications. + +.. note:: + If you have synchronized a Django project, you have already experienced + the use of one fixture -- the ``initial_data`` fixture. Every time you + synchronize the database, Django installs the ``initial_data`` fixture. + This provides a mechanism to populate a new database with any initial + data (such as a default set of categories). Fixtures with other names + can be installed manually using ``django-admin.py loaddata``. + + +However, for the purposes of unit testing, each test must be able to +guarantee the contents of the database at the start of each and every +test. To do this, Django provides a TestCase baseclass that can integrate +with fixtures. + +Moving from a normal unittest TestCase to a Django TestCase is easy - just +change the base class of your test, and define a list of fixtures +to be used. For example, the test case from `Writing unittests`_ would +look like:: + + from django.test import TestCase + from myapp.models import Animal + + class AnimalTestCase(TestCase): + fixtures = ['mammals.json', 'birds'] + + def setUp(self): + # test definitions as before + +At the start of each test case, before ``setUp()`` is run, Django will +flush the database, returning the database the state it was in directly +after ``syncdb`` was called. Then, all the named fixtures are installed. +In this example, any JSON fixture called ``mammals``, and any fixture +named ``birds`` will be installed. See the documentation on +`loading fixtures`_ for more details on defining and installing fixtures. + +.. _`loading fixtures`: ../django_admin/#loaddata-fixture-fixture + +This flush/load procedure is repeated for each test in the test case, so you +can be certain that the outcome of a test will not be affected by +another test, or the order of test execution. Running tests ============= @@ -335,13 +422,13 @@ but you only want to run the animals unit tests, run:: When you run your tests, you'll see a bunch of text flow by as the test database is created and models are initialized. This test database is -created from scratch every time you run your tests. +created from scratch every time you run your tests. -By default, the test database gets its name by prepending ``test_`` to -the database name specified by the ``DATABASE_NAME`` setting; all other +By default, the test database gets its name by prepending ``test_`` to +the database name specified by the ``DATABASE_NAME`` setting; all other database settings will the same as they would be for the project normally. -If you wish to use a name other than the default for the test database, -you can use the ``TEST_DATABASE_NAME`` setting to provide a name. +If you wish to use a name other than the default for the test database, +you can use the ``TEST_DATABASE_NAME`` setting to provide a name. Once the test database has been established, Django will run your tests. If everything goes well, at the end you'll see:: @@ -377,7 +464,10 @@ failed:: FAILED (failures=1) -When the tests have all been executed, the test database is destroyed. +The return code for the script will indicate the number of tests that failed. + +Regardless of whether the tests pass or fail, the test database is destroyed when +all the tests have been executed. Using a different testing framework =================================== @@ -388,7 +478,8 @@ it does provide a mechanism to allow you to invoke tests constructed for an alternative framework as if they were normal Django tests. When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER`` -setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django +setting to determine what to do. By default, ``TEST_RUNNER`` points to +``django.test.simple.run_tests``. This method defines the default Django testing behavior. This behavior involves: #. Performing global pre-test setup @@ -396,7 +487,7 @@ testing behavior. This behavior involves: #. Running ``syncdb`` to install models and initial data into the test database #. Looking for Unit Tests and Doctests in ``models.py`` and ``tests.py`` file for each installed application #. Running the Unit Tests and Doctests that are found -#. Destroying the test database. +#. Destroying the test database #. Performing global post-test teardown If you define your own test runner method and point ``TEST_RUNNER`` @@ -414,9 +505,11 @@ arguments: The module list is the list of Python modules that contain the models to be tested. This is the same format returned by ``django.db.models.get_apps()`` - Verbosity determines the amount of notification and debug information that + Verbosity determines the amount of notification and debug information that will be printed to the console; `0` is no output, `1` is normal output, and `2` is verbose output. + + This method should return the number of tests that failed. Testing utilities ----------------- @@ -425,12 +518,12 @@ To assist in the creation of your own test runner, Django provides a number of utility methods in the ``django.test.utils`` module. ``setup_test_environment()`` - Performs any global pre-test setup, such as the installing the - instrumentation of the template rendering system. + Performs any global pre-test setup, such as the installing the + instrumentation of the template rendering system. ``teardown_test_environment()`` - Performs any global post-test teardown, such as removing the instrumentation - of the template rendering system. + Performs any global post-test teardown, such as removing the instrumentation + of the template rendering system. ``create_test_db(verbosity=1, autoclobber=False)`` Creates a new test database, and run ``syncdb`` against it. diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt index 1b241f728a..56c5fa769e 100644 --- a/docs/tutorial01.txt +++ b/docs/tutorial01.txt @@ -19,6 +19,15 @@ installed. .. _`Django installed`: ../install/ +.. admonition:: Where to get help: + + If you're having trouble going through this tutorial, please post a message + to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll + try to help. + +.. _django-users: http://groups.google.com/group/django-users +.. _#django: irc://irc.freenode.net/django + Creating a project ================== @@ -32,6 +41,13 @@ 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. +.. note:: + + You'll need to avoid naming projects after built-in Python or Django + components. In particular, this means you should avoid using names like + ``django`` (which will conflict with Django itself) or ``site`` (which + conflicts with a built-in Python package). + (``django-admin.py`` should be on your system path if you installed Django via ``python setup.py``. If it's not on your path, you can find it in ``site-packages/django/bin``, where ``site-packages`` is a directory within diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt index 7b19bdaeaf..b1c8c7d4fc 100644 --- a/docs/tutorial04.txt +++ b/docs/tutorial04.txt @@ -206,6 +206,21 @@ for the polls app, we manually specify a template name for the results view: ``template_name='polls/results.html'``. Otherwise, both views would use the same template. Note that we use ``dict()`` to return an altered dictionary in place. +.. note:: ``all()`` is lazy + + It might look a little frightening to see ``Poll.objects.all()`` being used + in a detail view which only needs one ``Poll`` object, but don't worry; + ``Poll.objects.all()`` is actually a special object called a ``QuerySet``, + which is "lazy" and doesn't hit your database until it absolutely has to. By + the time the database query happens, the ``object_detail`` generic view will + have narrowed its scope down to a single object, so the eventual query will + only select one row from the database. + + If you'd like to know more about how that works, The Django database API + documentation `explains the lazy nature of QuerySet objects`_. + +.. _explains the lazy nature of QuerySet objects: ../db_api/#querysets-are-lazy + In previous parts of the tutorial, the templates have been provided with a context that contains the ``poll`` and ``latest_poll_list`` context variables. However, the generic views provide the variables ``object`` and ``object_list`` as context. diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt index da4be2c746..3f51ce4b91 100644 --- a/docs/url_dispatch.txt +++ b/docs/url_dispatch.txt @@ -390,6 +390,13 @@ to pass metadata and options to views. .. _generic views: ../generic_views/ .. _syndication framework: ../syndication/ +.. admonition:: Dealing with conflicts + + It's possible to have a URL pattern which captures named keyword arguments, + and also passes arguments with the same names in its dictionary of extra + arguments. When this happens, the arguments in the dictionary will be used + instead of the arguments captured in the URL. + Passing extra options to ``include()`` -------------------------------------- |
