magic-removal: Merged to [1903]
git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@1904 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
8f42a92465
commit
8013f76a40
1
AUTHORS
1
AUTHORS
|
@ -82,6 +82,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
phaedo <http://phaedo.cx/>
|
||||
Luke Plant <http://lukeplant.me.uk/>
|
||||
plisk
|
||||
Daniel Poelzleithner <http://poelzi.org/>
|
||||
Brian Ray <http://brianray.chipy.org/>
|
||||
Oliver Rutherfurd <http://rutherfurd.net/>
|
||||
David Schein
|
||||
|
|
|
@ -122,7 +122,7 @@ textarea { vertical-align:top !important; }
|
|||
input[type=text], input[type=password], textarea, select, .vTextField { border:1px solid #ccc; }
|
||||
|
||||
/* FORM BUTTONS */
|
||||
input[type=submit], input[type=button], .submit-row input { border:1px solid #ccc; background:white url(../img/admin/nav-bg.gif) bottom repeat-x; }
|
||||
input[type=submit], input[type=button], .submit-row input { border:1px solid #ccc; background:white url(../img/admin/nav-bg.gif) bottom repeat-x; color:black; }
|
||||
input[type=submit]:active, input[type=button]:active { background-image:url(../img/admin/nav-bg-reverse.gif); background-position:top; }
|
||||
input[type=submit].default, .submit-row input.default { border:2px solid #5b80b2; padding:3px; background:white url(../img/admin/default-bg.gif) bottom repeat-x; font-weight:bold; color:white; }
|
||||
input[type=submit].default:active { background-image:url(../img/admin/default-bg-reverse.gif); background-position:top; }
|
||||
|
@ -339,4 +339,4 @@ p img, h1 img, h2 img, h3 img, h4 img, td img { vertical-align:middle; }
|
|||
.vURLField { width:30em; }
|
||||
.vLargeTextField, .vXMLLargeTextField { width:48em; }
|
||||
.flatpages-flatpage #id_content { height:40.2em; }
|
||||
.module table .vPositiveSmallIntegerField { width:2.2em; }
|
||||
.module table .vPositiveSmallIntegerField { width:2.2em; }
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{% include "widget/foreign" %}
|
|
@ -811,7 +811,7 @@ class TimeField(TextField):
|
|||
if (len(part_list) == 2):
|
||||
t = t.replace(microsecond=int(part_list[1]))
|
||||
return t
|
||||
except (ValueError, TypeError):
|
||||
except (ValueError, TypeError, AttributeError):
|
||||
return None
|
||||
html2python = staticmethod(html2python)
|
||||
|
||||
|
|
|
@ -945,6 +945,12 @@ def createcachetable(tablename):
|
|||
connection.commit()
|
||||
createcachetable.args = "[tablename]"
|
||||
|
||||
def run_shell():
|
||||
"Runs a Python interactive interpreter"
|
||||
import code
|
||||
code.interact()
|
||||
run_shell.args = ''
|
||||
|
||||
# Utilities for command-line script
|
||||
|
||||
DEFAULT_ACTION_MAPPING = {
|
||||
|
@ -958,6 +964,7 @@ DEFAULT_ACTION_MAPPING = {
|
|||
'install': install,
|
||||
'installperms': installperms,
|
||||
'runserver': runserver,
|
||||
'shell': run_shell,
|
||||
'sql': get_sql_create,
|
||||
'sqlall': get_sql_all,
|
||||
'sqlclear': get_sql_delete,
|
||||
|
@ -1038,7 +1045,7 @@ def execute_from_command_line(action_mapping=DEFAULT_ACTION_MAPPING):
|
|||
sys.exit(1)
|
||||
else:
|
||||
action_mapping[action](username, email, password)
|
||||
elif action in ('init', 'init-minimal', 'validate'):
|
||||
elif action in ('init', 'init-minimal', 'shell', 'validate'):
|
||||
action_mapping[action]()
|
||||
elif action == 'inspectdb':
|
||||
try:
|
||||
|
|
|
@ -136,7 +136,7 @@ def wordwrap(value, arg):
|
|||
Argument: number of words to wrap the text at.
|
||||
"""
|
||||
from django.utils.text import wrap
|
||||
return wrap(value, int(arg))
|
||||
return wrap(str(value), int(arg))
|
||||
|
||||
def ljust(value, arg):
|
||||
"""
|
||||
|
|
|
@ -170,8 +170,8 @@ Change a password with ``set_password()``::
|
|||
Passwords
|
||||
---------
|
||||
|
||||
**This only applies to the Django development version.** Previous versions,
|
||||
such as Django 0.90, used simple MD5 hashes without password salts.
|
||||
Previous versions, such as Django 0.90, used simple MD5 hashes without password
|
||||
salts.
|
||||
|
||||
The ``password`` field of a ``User`` object is a string in this format::
|
||||
|
||||
|
@ -314,9 +314,8 @@ Here's the same thing, using Python 2.4's decorator syntax::
|
|||
Note that ``user_passes_test`` does not automatically check that the ``User``
|
||||
is not anonymous.
|
||||
|
||||
**New in the Django development version**: ``user_passes_test()`` takes an
|
||||
optional ``login_url`` argument, which lets you specify the URL for your login
|
||||
page (``/accounts/login/`` by default).
|
||||
``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
|
||||
specify the URL for your login page (``/accounts/login/`` by default).
|
||||
|
||||
Example in Python 2.3 syntax::
|
||||
|
||||
|
|
|
@ -48,8 +48,7 @@ Examples:
|
|||
locmem:/// A more sophisticated local memory cache;
|
||||
this is multi-process- and thread-safe.
|
||||
|
||||
dummy:/// **New in Django development version.**
|
||||
Doesn't actually cache; just implements the
|
||||
dummy:/// Doesn't actually cache; just implements the
|
||||
cache backend interface and doesn't do
|
||||
anything. This is an easy way to turn off
|
||||
caching for a test environment.
|
||||
|
|
|
@ -222,8 +222,6 @@ If you pass an invalid keyword argument, the function will raise ``TypeError``.
|
|||
OR lookups
|
||||
----------
|
||||
|
||||
**New in Django development version.**
|
||||
|
||||
By default, keyword argument queries are "AND"ed together. If you have more complex query
|
||||
requirements (for example, you need to include an ``OR`` statement in your query), you need
|
||||
to use ``Q`` objects.
|
||||
|
|
|
@ -6,14 +6,29 @@ The django-admin.py utility
|
|||
This document outlines all it can do.
|
||||
|
||||
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
|
||||
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``.
|
||||
|
||||
In addition, ``manage.py`` is automatically created in each Django project.
|
||||
``manage.py`` is a thin wrapper around ``django-admin.py`` that takes care of
|
||||
two things for you before delegating to ``django-admin.py``:
|
||||
|
||||
* It puts your project's package on ``sys.path``.
|
||||
|
||||
* It sets the ``DJANGO_SETTINGS_MODULE`` environment variable so that it
|
||||
points to your project's ``settings.py`` file.
|
||||
|
||||
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
|
||||
``--settings`` command line option, if you need to switch between multiple
|
||||
Django settings files.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
``django-admin.py action [options]``
|
||||
``manage.py action [options]``
|
||||
|
||||
``action`` should be one of the actions listed in this document. ``options``,
|
||||
which is optional, should be zero or more of the options listed in this
|
||||
|
@ -54,9 +69,8 @@ createsuperuser
|
|||
Creates a superuser account interactively. It asks you for a username, e-mail
|
||||
address and password.
|
||||
|
||||
**New in Django development version:** You can specify
|
||||
``username email password`` on the command line, for convenient use in shell
|
||||
scripts. Example::
|
||||
You can specify ``username email password`` on the command line, for convenient
|
||||
use in shell scripts. Example::
|
||||
|
||||
django-admin.py createsuperuser john john@example.com mypassword
|
||||
|
||||
|
@ -211,6 +225,9 @@ Explicitly specifies the settings module to use. The settings module should be
|
|||
in Python path syntax, e.g. "myproject.settings". If this isn't provided,
|
||||
``django-admin.py`` will use the DJANGO_SETTINGS_MODULE environment variable.
|
||||
|
||||
Note that this option is unnecessary in ``manage.py``, because it takes care of
|
||||
setting ``DJANGO_SETTINGS_MODULE`` for you.
|
||||
|
||||
--pythonpath
|
||||
------------
|
||||
|
||||
|
@ -222,6 +239,9 @@ Adds the given filesystem path to the Python `import search path`_. If this
|
|||
isn't provided, ``django-admin.py`` will use the ``PYTHONPATH`` environment
|
||||
variable.
|
||||
|
||||
Note that this option is unnecessary in ``manage.py``, because it takes care of
|
||||
setting the Python path for you.
|
||||
|
||||
.. _import search path: http://diveintopython.org/getting_to_know_python/everything_is_an_object.html
|
||||
|
||||
--help
|
||||
|
|
|
@ -118,8 +118,6 @@ receiving a separate e-mail::
|
|||
Preventing header injection
|
||||
===========================
|
||||
|
||||
**New in Django development version.**
|
||||
|
||||
`Header injection`_ is a security exploit in which an attacker inserts extra
|
||||
e-mail headers to control the "To:" and "From:" in e-mail messages that your
|
||||
scripts generate.
|
||||
|
|
|
@ -129,9 +129,9 @@ arguments:
|
|||
``extra_context`` A dictionary of extra data to put into the
|
||||
template's context.
|
||||
|
||||
``processors`` **New in Django development version.** A tuple of
|
||||
processors to apply to the ``DjangoContext`` of
|
||||
this view's template. See the `DjangoContext docs`_
|
||||
``processors`` A tuple of processors to apply to the
|
||||
``DjangoContext`` of this view's template. See the
|
||||
`DjangoContext docs`_
|
||||
======================= ==================================================
|
||||
|
||||
.. _database API docs: http://www.djangoproject.com/documentation/db_api/
|
||||
|
@ -150,8 +150,7 @@ The date-based generic functions are:
|
|||
``num_latest`` The number of items to display on the page.
|
||||
Defaults to 15.
|
||||
|
||||
``allow_empty`` **New in Django development version.**
|
||||
If ``False`` and there are no objects to display,
|
||||
``allow_empty`` If ``False`` and there are no objects to display,
|
||||
the view will raise a 404 instead of displaying
|
||||
an empty index page. ``False`` is default.
|
||||
======================= =================================================
|
||||
|
|
|
@ -151,9 +151,8 @@ subclass of dictionary. Exceptions are outlined here:
|
|||
other dictionary functions that have side effects, can only be called on
|
||||
a mutable ``QueryDict`` (one that was created via ``copy()``).
|
||||
|
||||
* ``__contains__(key)`` -- **New in Django development version.** Returns
|
||||
``True`` if the given key is set. This lets you do, e.g.,
|
||||
``if "foo" in request.GET``.
|
||||
* ``__contains__(key)`` -- Returns ``True`` if the given key is set. This
|
||||
lets you do, e.g., ``if "foo" in request.GET``.
|
||||
|
||||
* ``get(key, default)`` -- Uses the same logic as ``__getitem__()`` above,
|
||||
with a hook for returning a default value if the key doesn't exist.
|
||||
|
@ -361,8 +360,6 @@ types of HTTP responses. Like ``HttpResponse``, these subclasses live in
|
|||
an HTTP status code 302.
|
||||
|
||||
``HttpResponsePermanentRedirect``
|
||||
**New in Django development version.***
|
||||
|
||||
Like ``HttpResponseRedirect``, but it returns a permanent redirect (HTTP
|
||||
status code 301) instead of a "found" redirect (status code 302).
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ it and write to it.
|
|||
It implements the following standard dictionary methods:
|
||||
|
||||
* ``__contains__(key)``
|
||||
**New in Django development version.** Example: ``'fav_color' in request.session``
|
||||
Example: ``'fav_color' in request.session``
|
||||
|
||||
* ``__getitem__(key)``
|
||||
Example: ``fav_color = request.session['fav_color']``
|
||||
|
@ -177,10 +177,9 @@ deleted::
|
|||
# request.session['foo'] instead of request.session.
|
||||
request.session['foo']['bar'] = 'baz'
|
||||
|
||||
**Only available in Django development version.** To change this default
|
||||
behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting to ``True``. If
|
||||
``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save the session to the
|
||||
database on every single request.
|
||||
To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting
|
||||
to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save
|
||||
the session to the database on every single request.
|
||||
|
||||
Note that the session cookie is only sent when a session has been created or
|
||||
modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, the session cookie
|
||||
|
@ -213,8 +212,7 @@ domain cookie.
|
|||
SESSION_COOKIE_NAME
|
||||
-------------------
|
||||
|
||||
Default: ``'sessionid'`` (**Django development version.** Previous default was
|
||||
``'hotclub'``, which was deemed too pornish.)
|
||||
Default: ``'sessionid'``
|
||||
|
||||
The name of the cookie to use for sessions. This can be whatever you want.
|
||||
|
||||
|
@ -223,8 +221,6 @@ SESSION_SAVE_EVERY_REQUEST
|
|||
|
||||
Default: ``False``
|
||||
|
||||
**Only available in Django development version.**
|
||||
|
||||
Whether to save the session data on every request. If this is ``False``
|
||||
(default), then the session data will only be saved if it has been modified --
|
||||
that is, if any of its dictionary values have been assigned or deleted.
|
||||
|
|
|
@ -525,8 +525,7 @@ domain cookie. See the `session docs`_.
|
|||
SESSION_COOKIE_NAME
|
||||
-------------------
|
||||
|
||||
Default: ``'sessionid'`` (**Django development version.** Previous default was
|
||||
``'hotclub'``, which was deemed too pornish.)
|
||||
Default: ``'sessionid'``
|
||||
|
||||
The name of the cookie to use for sessions. This can be whatever you want.
|
||||
See the `session docs`_.
|
||||
|
@ -556,8 +555,6 @@ Default::
|
|||
"django.core.context_processors.debug",
|
||||
"django.core.context_processors.i18n")
|
||||
|
||||
**Only available in Django development version.**
|
||||
|
||||
A tuple of callables that are used to populate the context in ``DjangoContext``.
|
||||
These callables take a request object as their argument and return a dictionary
|
||||
of items to be merged into the context.
|
||||
|
@ -567,8 +564,6 @@ TEMPLATE_DEBUG
|
|||
|
||||
Default: ``False``
|
||||
|
||||
**Only available in Django development version.**
|
||||
|
||||
A boolean that turns on/off template debug mode. If this is ``True``, the fancy
|
||||
error page will display a detailed report for any ``TemplateSyntaxError``. This
|
||||
report contains the relevant snippet of the template, with the appropriate line
|
||||
|
|
|
@ -278,8 +278,8 @@ In the above, the ``load`` tag loads the ``comments`` tag library, which then
|
|||
makes the ``comment_form`` tag available for use. Consult the documentation
|
||||
area in your admin to find the list of custom libraries in your installation.
|
||||
|
||||
**New in Django development version:** The ``{% load %}`` tag can take multiple
|
||||
library names, separated by spaces. Example::
|
||||
The ``{% load %}`` tag can take multiple library names, separated by spaces.
|
||||
Example::
|
||||
|
||||
{% load comments i18n %}
|
||||
|
||||
|
@ -500,8 +500,6 @@ Just like ``ifequal``, except it tests that the two arguments are not equal.
|
|||
include
|
||||
~~~~~~~
|
||||
|
||||
**Only available in Django development version.**
|
||||
|
||||
Loads a template and renders it with the current context. This is a way of
|
||||
"including" other templates within a template.
|
||||
|
||||
|
|
|
@ -282,11 +282,6 @@ optional, third positional argument, ``processors``. In this example, the
|
|||
'foo': 'bar',
|
||||
}, [ip_address_processor])
|
||||
|
||||
Note: The concept of template-context processors is new in the Django
|
||||
development version. In Django 0.90, ``DjangoContext`` automatically populates
|
||||
the context with all of the values explained below, but it's not possible to
|
||||
add and remove processors.
|
||||
|
||||
Here's what each of the default processors does:
|
||||
|
||||
.. _HttpRequest object: http://www.djangoproject.com/documentation/request_response/#httprequest-objects
|
||||
|
@ -540,8 +535,6 @@ filters are registered. So, near the top of your module, put the following::
|
|||
Writing custom template filters
|
||||
-------------------------------
|
||||
|
||||
**This section applies to the Django development version.**
|
||||
|
||||
Custom filters are just Python functions that take one or two arguments:
|
||||
|
||||
* The value of the variable (input) -- not necessarily a string.
|
||||
|
@ -601,8 +594,6 @@ will use the function's name as the filter name.
|
|||
Writing custom template tags
|
||||
----------------------------
|
||||
|
||||
**This section applies to the Django development version.**
|
||||
|
||||
Tags are more complex than filters, because tags can do anything.
|
||||
|
||||
A quick overview
|
||||
|
|
|
@ -34,15 +34,15 @@ on your path, such as /usr/local/bin.)
|
|||
|
||||
.. admonition:: Where should this code live?
|
||||
|
||||
If your background is in PHP, you're probably used to putting code under the
|
||||
Web server's document root (in a place such as ``/var/www``). With Django,
|
||||
you don't do that. It's not a good idea to put any of this Python code within
|
||||
your Web server's document root, because it risks the possibility that
|
||||
people may be able to view your code over the Web. That's not good for
|
||||
security.
|
||||
If your background is in PHP, you're probably used to putting code under the
|
||||
Web server's document root (in a place such as ``/var/www``). With Django,
|
||||
you don't do that. It's not a good idea to put any of this Python code within
|
||||
your Web server's document root, because it risks the possibility that
|
||||
people may be able to view your code over the Web. That's not good for
|
||||
security.
|
||||
|
||||
Put your code in some directory **outside** of the document root, such as
|
||||
``/home/mycode``.
|
||||
Put your code in some directory **outside** of the document root, such as
|
||||
``/home/mycode``.
|
||||
|
||||
A project is a collection of settings for an instance of Django -- including
|
||||
database configuration, Django-specific options and application-specific
|
||||
|
@ -50,24 +50,68 @@ settings. Let's look at what ``startproject`` created::
|
|||
|
||||
myproject/
|
||||
__init__.py
|
||||
apps/
|
||||
__init__.py
|
||||
manage.py
|
||||
settings.py
|
||||
urls.py
|
||||
|
||||
First, edit ``myproject/settings.py``. It's a normal Python module with
|
||||
module-level variables representing Django settings. Edit the file and change
|
||||
these settings to match your database's connection parameters:
|
||||
These files are:
|
||||
|
||||
* ``manage.py``: A command-line utility that lets you interact with this
|
||||
Django project in various ways.
|
||||
* ``settings.py``: Settings/configuration for this Django project.
|
||||
* ``urls.py``: The URL declarations for this Django project; a "table of
|
||||
contents" of your Django-powered site.
|
||||
|
||||
The development server
|
||||
----------------------
|
||||
|
||||
Change into the ``myproject`` directory, if you haven't already, and run the
|
||||
command ``python manage.py runserver``. You'll see the following output on the
|
||||
command line::
|
||||
|
||||
Validating models...
|
||||
0 errors found.
|
||||
|
||||
Starting server on port 8000 with settings module 'myproject.settings'.
|
||||
Go to http://127.0.0.1:8000/ for Django.
|
||||
Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
|
||||
|
||||
You've started the Django development server, a lightweight, pure-Python Web
|
||||
server that builds on the BaseHTTPServer included in Python's standard library.
|
||||
We've included this with Django so you can develop things rapidly, without
|
||||
having to deal with configuring Apache until you're ready for production.
|
||||
|
||||
DON'T use this server in anything resembling a production environment. It's
|
||||
intended only for use while developing.
|
||||
|
||||
.. admonition:: Changing the port
|
||||
|
||||
By default, the ``runserver`` command starts the development server on port
|
||||
8000. If you want to change the server's port, pass it as a command-line
|
||||
argument::
|
||||
|
||||
python manage.py runserver 8080
|
||||
|
||||
Now that the server's running, visit http://127.0.0.1:8000/ with your Web
|
||||
browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel.
|
||||
It worked!
|
||||
|
||||
Database setup
|
||||
--------------
|
||||
|
||||
Now, edit ``settings.py``. It's a normal Python module with module-level
|
||||
variables representing Django settings. Change these settings to match your
|
||||
database's connection parameters:
|
||||
|
||||
* ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'.
|
||||
More coming soon.
|
||||
* ``DATABASE_NAME`` -- The name of your database, or the full (absolute)
|
||||
path to the database file if you're using sqlite.
|
||||
* ``DATABASE_USER`` -- Your database username (not used for sqlite).
|
||||
* ``DATABASE_PASSWORD`` -- Your database password (not used for sqlite).
|
||||
path to the database file if you're using SQLite.
|
||||
* ``DATABASE_USER`` -- Your database username (not used for SQLite).
|
||||
* ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite).
|
||||
* ``DATABASE_HOST`` -- The host your database is on. Leave this as an
|
||||
empty string if your database server is on the same physical machine
|
||||
(not used for sqlite).
|
||||
(not used for SQLite).
|
||||
|
||||
.. admonition:: Note
|
||||
|
||||
|
@ -75,67 +119,55 @@ these settings to match your database's connection parameters:
|
|||
point. Do that with "``CREATE DATABASE database_name;``" within your
|
||||
database's interactive prompt.
|
||||
|
||||
Now, take a second to make sure ``myproject`` is on your Python path. You
|
||||
can do this by copying ``myproject`` to Python's ``site-packages`` directory,
|
||||
or you can do it by altering the ``PYTHONPATH`` environment variable. See the
|
||||
`Python path documentation`_ for more information. If you opt to set the
|
||||
``PYTHONPATH`` environment variable, note that you'll need to set it to the
|
||||
*parent* directory of ``myproject``. (You can test this by typing
|
||||
"import myproject" into the Python interactive prompt.)
|
||||
Run the following command to initialize your database with Django's core
|
||||
database tables::
|
||||
|
||||
Run the following command::
|
||||
python manage.py init
|
||||
|
||||
django-admin.py init --settings=myproject.settings
|
||||
If you don't see any errors, it worked.
|
||||
|
||||
The ``django-admin.py`` utility generally needs to know which settings module
|
||||
you're using. Here, we're doing that by specifying ``settings=`` on the command
|
||||
line, but that can get tedious. If you don't want to type ``settings=`` each
|
||||
time, you can set the ``DJANGO_SETTINGS_MODULE`` environment variable. Here's
|
||||
how you do that in the Bash shell on Unix::
|
||||
If you're interested, run the command-line client for your database and type
|
||||
``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
|
||||
display the tables Django created.
|
||||
|
||||
export DJANGO_SETTINGS_MODULE=myproject.settings
|
||||
.. admonition:: About those database tables
|
||||
|
||||
On Windows, you'd use ``set`` instead::
|
||||
|
||||
set DJANGO_SETTINGS_MODULE=myproject.settings
|
||||
|
||||
If you don't see any errors after running ``django-admin.py init``, you know it
|
||||
worked. That command initialized your database with Django's core database
|
||||
tables. If you're interested, run the command-line client for your database and
|
||||
type ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
|
||||
display the tables.
|
||||
|
||||
.. _`Python path documentation`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
|
||||
The tables created by ``manage.py init`` are for sessions, authentication
|
||||
and other features Django provides. The next release of Django will have
|
||||
a "lite" version of the ``init`` command that won't install any database
|
||||
tables if you don't want them.
|
||||
|
||||
Creating models
|
||||
===============
|
||||
|
||||
Now that your environment -- a "project" -- is set up, you're set to start
|
||||
doing work. (You won't have to take care of this boring administrative stuff
|
||||
doing work. (You won't have to take care of that boring administrative stuff
|
||||
again.)
|
||||
|
||||
Each application you write in Django -- e.g., a weblog system, a database of
|
||||
public records or a simple poll app -- consists of a Python package, somewhere
|
||||
on your Python path, that follows a certain convention. Django comes with a
|
||||
Each application you write in Django consists of a Python package, somewhere
|
||||
on your `Python path`_, that follows a certain convention. Django comes with a
|
||||
utility that automatically generates the basic directory structure of an app,
|
||||
so you can focus on writing code rather than creating directories.
|
||||
|
||||
In this tutorial, we'll create our poll app in the ``myproject/apps``
|
||||
directory, for simplicity. As a consequence, the app will be coupled to the
|
||||
project -- that is, Python code within the poll app will refer to
|
||||
``myproject.apps.polls``. Later in this tutorial, we'll discuss decoupling
|
||||
your apps for distribution.
|
||||
.. admonition:: Projects vs. apps
|
||||
|
||||
To create your app, change into the ``myproject/apps`` directory and type this
|
||||
command::
|
||||
What's the difference between a project and an app? An app is a Web
|
||||
application that does something -- e.g., a weblog system, a database of
|
||||
public records or a simple poll app. A project is a collection of
|
||||
configuration and apps for a particular Web site. A project can contain
|
||||
multiple apps. An app can be in multiple projects.
|
||||
|
||||
django-admin.py startapp polls
|
||||
In this tutorial, we'll create our poll app in the ``myproject`` directory,
|
||||
for simplicity. As a consequence, the app will be coupled to the project --
|
||||
that is, Python code within the poll app will refer to ``myproject.polls``.
|
||||
Later in this tutorial, we'll discuss decoupling your apps for distribution.
|
||||
|
||||
(From now on, this tutorial will leave out the ``--settings`` parameter and
|
||||
will assume you've either set your ``DJANGO_SETTINGS_MODULE`` environment
|
||||
variable or included the ``--settings`` option in your call to the command.)
|
||||
To create your app, make sure you're in the ``myproject`` directory and type
|
||||
this command::
|
||||
|
||||
That'll create a directory structure like this::
|
||||
python manage.py startapp polls
|
||||
|
||||
That'll create a directory ``polls``, which is laid out like this::
|
||||
|
||||
polls/
|
||||
__init__.py
|
||||
|
@ -201,6 +233,7 @@ Finally, note a relationship is defined, using ``meta.ForeignKey``. That tells
|
|||
Django each Choice is related to a single Poll. Django supports all the common
|
||||
database relationships: many-to-ones, many-to-manys and one-to-ones.
|
||||
|
||||
.. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
|
||||
.. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself
|
||||
|
||||
Activating models
|
||||
|
@ -209,32 +242,30 @@ Activating models
|
|||
That small bit of model code gives Django a lot of information. With it, Django
|
||||
is able to:
|
||||
|
||||
* Create a database schema (``CREATE TABLE`` statements) for this app.
|
||||
* Create a Python database-access API for accessing Poll and Choice objects.
|
||||
* Create a database schema (``CREATE TABLE`` statements) for this app.
|
||||
* Create a Python database-access API for accessing Poll and Choice objects.
|
||||
|
||||
But first we need to tell our project that the ``polls`` app is installed.
|
||||
|
||||
.. admonition:: Philosophy
|
||||
|
||||
Django apps are "pluggable": You can use an app in multiple
|
||||
projects, and you can distribute apps, because they don't have to be tied to
|
||||
a given Django installation.
|
||||
Django apps are "pluggable": You can use an app in multiple projects, and
|
||||
you can distribute apps, because they don't have to be tied to a given
|
||||
Django installation.
|
||||
|
||||
Edit the myproject/settings.py file again, and change the ``INSTALLED_APPS``
|
||||
setting to include the string "myproject.apps.polls". So it'll look like this::
|
||||
Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting
|
||||
to include the string ``'myproject.polls'``. So it'll look like this::
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'myproject.apps.polls',
|
||||
'myproject.polls',
|
||||
)
|
||||
|
||||
(Don't forget the trailing comma because of Python's rules about single-value
|
||||
tuples.)
|
||||
(Don't forget the trailing comma, because of Python's rule about single-value
|
||||
tuples: Without a trailing comma, Python wouldn't know this was a tuple.)
|
||||
|
||||
Now Django knows myproject includes the polls app. Let's run another command::
|
||||
Now Django knows ``myproject`` includes the ``polls`` app. Let's run another command::
|
||||
|
||||
django-admin.py sql polls
|
||||
|
||||
(Note that it doesn't matter which directory you're in when you run this command.)
|
||||
python manage.py sql polls
|
||||
|
||||
You should see the following (the CREATE TABLE SQL statements for the polls app)::
|
||||
|
||||
|
@ -255,8 +286,8 @@ You should see the following (the CREATE TABLE SQL statements for the polls app)
|
|||
Note the following:
|
||||
|
||||
* Table names are automatically generated by combining the name of the app
|
||||
(polls) with a plural version of the object name (polls and choices). (You
|
||||
can override this behavior.)
|
||||
(``polls``) with a plural version of the object name (polls and choices).
|
||||
(You can override this behavior.)
|
||||
|
||||
* Primary keys (IDs) are added automatically. (You can override this, too.)
|
||||
|
||||
|
@ -265,26 +296,26 @@ Note the following:
|
|||
|
||||
* The foreign key relationship is made explicit by a ``REFERENCES`` statement.
|
||||
|
||||
* It's tailored to the database you're using, so database-specific field types
|
||||
such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or ``integer
|
||||
primary key`` (SQLite) are handled for you automatically. Same goes for
|
||||
quoting of field names -- e.g., using double quotes or single quotes. The
|
||||
author of this tutorial runs PostgreSQL, so the example output is in
|
||||
PostgreSQL syntax.
|
||||
* It's tailored to the database you're using, so database-specific field
|
||||
types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
|
||||
``integer primary key`` (SQLite) are handled for you automatically. Same
|
||||
goes for quoting of field names -- e.g., using double quotes or single
|
||||
quotes. The author of this tutorial runs PostgreSQL, so the example
|
||||
output is inPostgreSQL syntax.
|
||||
|
||||
If you're interested, also run the following commands:
|
||||
|
||||
* ``django-admin.py sqlinitialdata polls`` -- Outputs the initial-data
|
||||
* ``python manage.py sqlinitialdata polls`` -- Outputs the initial-data
|
||||
inserts required for Django's admin framework.
|
||||
|
||||
* ``django-admin.py sqlclear polls`` -- Outputs the necessary ``DROP
|
||||
* ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
|
||||
TABLE`` statements for this app, according to which tables already exist
|
||||
in your database (if any).
|
||||
|
||||
* ``django-admin.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
|
||||
* ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
|
||||
statements for this app.
|
||||
|
||||
* ``django-admin.py sqlall polls`` -- A combination of 'sql' and
|
||||
* ``python manage.py sqlall polls`` -- A combination of 'sql' and
|
||||
'sqlinitialdata'.
|
||||
|
||||
Looking at the output of those commands can help you understand what's actually
|
||||
|
@ -293,23 +324,50 @@ happening under the hood.
|
|||
Now, run this command to create the database tables for the polls app
|
||||
automatically::
|
||||
|
||||
django-admin.py install polls
|
||||
python manage.py install polls
|
||||
|
||||
Behind the scenes, all that command does is take the output of
|
||||
``django-admin.py sqlall polls`` and execute it in the database pointed-to by
|
||||
``python manage.py sqlall polls`` and execute it in the database pointed-to by
|
||||
your Django settings file.
|
||||
|
||||
Read the `django-admin.py documentation`_ for full information on what this
|
||||
utility can do.
|
||||
Read the `django-admin.py documentation`_ for full information on what the
|
||||
``manage.py`` utility can do.
|
||||
|
||||
.. _django-admin.py documentation: http://www.djangoproject.com/documentation/django_admin/
|
||||
|
||||
Playing with the API
|
||||
====================
|
||||
|
||||
Now, make sure your DJANGO_SETTINGS_MODULE environment variable is set (as
|
||||
explained above), and open the Python interactive shell to play around with the
|
||||
free Python API Django gives you::
|
||||
Now, let's hop into the interactive Python shell and play around with the free
|
||||
API Django gives you. To invoke the Python shell, use this command::
|
||||
|
||||
python manage.py shell
|
||||
|
||||
We're using this instead of simply typing "python", because ``manage.py`` sets
|
||||
up the project's environment for you. "Setting up the environment" involves two
|
||||
things:
|
||||
|
||||
* Putting ``myproject`` on ``sys.path``. For flexibility, several pieces of
|
||||
Django refer to projects in Python dotted-path notation (e.g.
|
||||
``'myproject.polls.models'``). In order for this to work, the
|
||||
``myproject`` package has to be on ``sys.path``.
|
||||
|
||||
We've already seen one example of this: the ``INSTALLED_APPS`` setting is
|
||||
a list of packages in dotted-path notation.
|
||||
|
||||
* Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives
|
||||
Django the path to your ``settings.py`` file.
|
||||
|
||||
.. admonition:: Bypassing manage.py
|
||||
|
||||
If you'd rather not use ``manage.py``, no problem. Just make sure
|
||||
``myproject`` is at the root level on the Python path (i.e.,
|
||||
``import myproject`` works) and set the ``DJANGO_SETTINGS_MODULE``
|
||||
environment variable to ``myproject.settings``.
|
||||
|
||||
For more information on all of this, see the `django-admin.py documentation`_.
|
||||
|
||||
Once you're in the shell, explore the database API::
|
||||
|
||||
# Modules are dynamically created within django.models.
|
||||
# Their names are plural versions of the model class names.
|
||||
|
@ -326,7 +384,10 @@ free Python API Django gives you::
|
|||
# Save the object into the database. You have to call save() explicitly.
|
||||
>>> p.save()
|
||||
|
||||
# Now it has an ID.
|
||||
# Now it has an ID. Note that this might say "1L" instead of "1", depending
|
||||
# on which database you're using. That's no biggie; it just means your
|
||||
# database backend prefers to return integers as Python long integer
|
||||
# objects.
|
||||
>>> p.id
|
||||
1
|
||||
|
||||
|
@ -375,7 +436,8 @@ Note ``import datetime`` wasn't necessary. Each model method has access to
|
|||
a handful of commonly-used variables for convenience, including the
|
||||
``datetime`` module from the Python standard library.
|
||||
|
||||
Let's jump back into the Python interactive shell::
|
||||
Let's jump back into the Python interactive shell by running
|
||||
``python manage.py shell`` again::
|
||||
|
||||
>>> from django.models.polls import polls, choices
|
||||
# Make sure our __repr__() addition worked.
|
||||
|
|
|
@ -31,7 +31,7 @@ The Django admin site is not activated by default -- it's an opt-in thing. To
|
|||
activate the admin site for your installation, do these three things:
|
||||
|
||||
* Add ``"django.contrib.admin"`` to your ``INSTALLED_APPS`` setting.
|
||||
* Run the command ``django-admin.py install admin``. This will create an
|
||||
* Run the command ``python manage.py install admin``. This will create an
|
||||
extra database table that the admin needs.
|
||||
* Edit your ``myproject/urls.py`` file and uncomment the line below
|
||||
"Uncomment this for admin:". This file is a URLconf; we'll dig into
|
||||
|
@ -43,28 +43,18 @@ Create a user account
|
|||
|
||||
Run the following command to create a superuser account for your admin site::
|
||||
|
||||
django-admin.py createsuperuser --settings=myproject.settings
|
||||
python manage.py createsuperuser
|
||||
|
||||
The script will prompt you for a username, e-mail address and password (twice).
|
||||
|
||||
Start the development server
|
||||
============================
|
||||
|
||||
To make things easy, Django comes with a pure-Python Web server that builds on
|
||||
the BaseHTTPServer included in Python's standard library. Let's start the
|
||||
server and explore the admin site.
|
||||
Let's start the development server and explore the admin site.
|
||||
|
||||
Just run the following command to start the server::
|
||||
Recall from Tutorial 1 that you start the development server like so::
|
||||
|
||||
django-admin.py runserver --settings=myproject.settings
|
||||
|
||||
It'll start a Web server running locally -- on port 8000, by default. If you
|
||||
want to change the server's port, pass it as a command-line argument::
|
||||
|
||||
django-admin.py runserver 8080 --settings=myproject.settings
|
||||
|
||||
DON'T use this server in anything resembling a production environment. It's
|
||||
intended only for use while developing.
|
||||
python manage.py runserver
|
||||
|
||||
Now, open a Web browser and go to "/admin/" on your local domain -- e.g.,
|
||||
http://127.0.0.1:8000/admin/. You should see the admin's login screen:
|
||||
|
@ -91,8 +81,8 @@ Make the poll app modifiable in the admin
|
|||
|
||||
But where's our poll app? It's not displayed on the admin index page.
|
||||
|
||||
Just one thing to do: We need to specify in the ``polls.Poll`` model that Poll
|
||||
objects have an admin interface. Edit the ``myproject/apps/polls/models/polls.py``
|
||||
Just one thing to do: We need to specify in the ``Poll`` model that ``Poll``
|
||||
objects have an admin interface. Edit the ``myproject/polls/models/polls.py``
|
||||
file and make the following change to add an inner ``Meta`` class with an
|
||||
``admin`` attribute::
|
||||
|
||||
|
@ -101,11 +91,13 @@ file and make the following change to add an inner ``Meta`` class with an
|
|||
class Meta:
|
||||
admin = meta.Admin()
|
||||
|
||||
The ``class Meta`` contains all non-field metadata about this model.
|
||||
The ``class Meta`` contains all `non-field metadata`_ about this model.
|
||||
|
||||
Now reload the Django admin page to see your changes. Note that you don't have
|
||||
to restart the development server -- it auto-reloads code.
|
||||
|
||||
.. _non-field metadata: http://www.djangoproject.com/documentation/model_api/#meta-options
|
||||
|
||||
Explore the free admin functionality
|
||||
====================================
|
||||
|
||||
|
@ -216,14 +208,14 @@ aren't commonly used::
|
|||
Adding related objects
|
||||
======================
|
||||
|
||||
OK, we have our Poll admin page. But a ``Poll`` has multiple ``Choices``, and the admin
|
||||
page doesn't display choices.
|
||||
OK, we have our Poll admin page. But a ``Poll`` has multiple ``Choices``, and
|
||||
the admin page doesn't display choices.
|
||||
|
||||
Yet.
|
||||
|
||||
In this case, there are two ways to solve this problem. The first is to give
|
||||
the ``Choice`` model its own ``admin`` attribute, just as we did with ``Poll``.
|
||||
Here's what that would look like::
|
||||
There are two ways to solve this problem. The first is to give the ``Choice``
|
||||
model its own ``admin`` attribute, just as we did with ``Poll``. Here's what
|
||||
that would look like::
|
||||
|
||||
class Choice(meta.Model):
|
||||
# ...
|
||||
|
@ -237,7 +229,8 @@ looks like this:
|
|||
:alt: Choice admin page
|
||||
|
||||
In that form, the "Poll" field is a select box containing every poll in the
|
||||
database. In our case, only one poll exists at this point.
|
||||
database. Django knows that a ``ForeignKey`` should be represented in the admin
|
||||
as a ``<select>`` box. In our case, only one poll exists at this point.
|
||||
|
||||
Also note the "Add Another" link next to "Poll." Every object with a ForeignKey
|
||||
relationship to another gets this for free. When you click "Add Another," you'll
|
||||
|
@ -363,7 +356,7 @@ This is shaping up well. Let's add some search capability::
|
|||
|
||||
That adds a search box at the top of the change list. When somebody enters
|
||||
search terms, Django will search the ``question`` field. You can use as many
|
||||
fields as you'd like -- although because it uses a LIKE query behind the
|
||||
fields as you'd like -- although because it uses a ``LIKE`` query behind the
|
||||
scenes, keep it reasonable, to keep your database happy.
|
||||
|
||||
Finally, because Poll objects have dates, it'd be convenient to be able to
|
||||
|
@ -444,7 +437,7 @@ hard-code links to object-specific admin pages in whatever way you think is
|
|||
best.
|
||||
|
||||
Django offers another shortcut in this department. Run the command
|
||||
``django-admin.py adminindex polls`` to get a chunk of template code for
|
||||
``python manage.py adminindex polls`` to get a chunk of template code for
|
||||
inclusion in the admin index template. It's a useful starting point.
|
||||
|
||||
For full details on customizing the look and feel of the Django admin site in
|
||||
|
|
|
@ -62,7 +62,7 @@ arguments from the dictionary (an optional third item in the tuple).
|
|||
For more on ``HTTPRequest`` objects, see the `request and response documentation`_.
|
||||
For more details on URLconfs, see the `URLconf documentation`_.
|
||||
|
||||
When you ran ``django-admin.py startproject myproject`` at the beginning of
|
||||
When you ran ``python manage.py startproject myproject`` at the beginning of
|
||||
Tutorial 1, it created a default URLconf in ``myproject/urls.py``. It also
|
||||
automatically set your ``ROOT_URLCONF`` setting to point at that file::
|
||||
|
||||
|
@ -73,33 +73,33 @@ Time for an example. Edit ``myproject/urls.py`` so it looks like this::
|
|||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^polls/$', 'myproject.apps.polls.views.index'),
|
||||
(r'^polls/(?P<poll_id>\d+)/$', 'myproject.apps.polls.views.detail'),
|
||||
(r'^polls/(?P<poll_id>\d+)/results/$', 'myproject.apps.polls.views.results'),
|
||||
(r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.apps.polls.views.vote'),
|
||||
(r'^polls/$', 'myproject.polls.views.index'),
|
||||
(r'^polls/(\d+)/$', 'myproject.polls.views.detail'),
|
||||
(r'^polls/(\d+)/results/$', 'myproject.polls.views.results'),
|
||||
(r'^polls/(\d+)/vote/$', 'myproject.polls.views.vote'),
|
||||
)
|
||||
|
||||
This is worth a review. When somebody requests a page from your Web site --
|
||||
say, "/polls/23/", Django will load this Python module, because it's pointed to
|
||||
by the ``ROOT_URLCONF`` setting. It finds the variable named ``urlpatterns``
|
||||
and traverses the regular expressions in order. When it finds a regular
|
||||
expression that matches -- ``r'^polls/(?P<poll_id>\d+)/$'`` -- it loads the
|
||||
associated Python package/module: ``myproject.apps.polls.views.detail``. That
|
||||
corresponds to the function ``detail()`` in ``myproject/apps/polls/views.py``.
|
||||
expression that matches -- ``r'^polls/(\d+)/$'`` -- it loads the
|
||||
associated Python package/module: ``myproject.polls.views.detail``. That
|
||||
corresponds to the function ``detail()`` in ``myproject/polls/views.py``.
|
||||
Finally, it calls that ``detail()`` function like so::
|
||||
|
||||
detail(request=<HttpRequest object>, poll_id='23')
|
||||
|
||||
The ``poll_id='23'`` part comes from ``(?P<poll_id>\d+)``. Using
|
||||
``(?P<name>pattern)`` "captures" the text matched by ``pattern`` and sends it
|
||||
as a keyword argument to the view function.
|
||||
The ``poll_id='23'`` part comes from ``(\d+)``. Using parenthesis around a
|
||||
pattern "captures" the text matched by that pattern and sends it as an argument
|
||||
to the view function.
|
||||
|
||||
Because the URL patterns are regular expressions, there really is no limit on
|
||||
what you can do with them. And there's no need to add URL cruft such as
|
||||
``.php`` -- unless you have a sick sense of humor, in which case you can do
|
||||
something like this::
|
||||
|
||||
(r'^polls/latest\.php$', 'myproject.apps.polls.views.index'),
|
||||
(r'^polls/latest\.php$', 'myproject.polls.views.index'),
|
||||
|
||||
But, don't do that. It's silly.
|
||||
|
||||
|
@ -128,24 +128,24 @@ make sure Django is following the URLconf properly.
|
|||
|
||||
Fire up the Django development Web server::
|
||||
|
||||
django-admin.py runserver --settings=myproject.settings
|
||||
python manage.py runserver
|
||||
|
||||
Now go to "http://localhost:8000/polls/" on your domain in your Web browser.
|
||||
You should get a pleasantly-colored error page with the following message::
|
||||
|
||||
ViewDoesNotExist at /polls/
|
||||
|
||||
Tried index in module myproject.apps.polls.views. Error was: 'module'
|
||||
Tried index in module myproject.polls.views. Error was: 'module'
|
||||
object has no attribute 'index'
|
||||
|
||||
This error happened because you haven't written a function ``index()`` in the
|
||||
module ``myproject/apps/polls/views.py``.
|
||||
module ``myproject/polls/views.py``.
|
||||
|
||||
Try "/polls/23/", "/polls/23/results/" and "/polls/23/vote/". The error
|
||||
messages tell you which view Django tried (and failed to find, because you
|
||||
haven't written any views yet).
|
||||
|
||||
Time to write the first view. Open the file ``myproject/apps/polls/views.py``
|
||||
Time to write the first view. Open the file ``myproject/polls/views.py``
|
||||
and put the following Python code in it::
|
||||
|
||||
from django.utils.httpwrappers import HttpResponse
|
||||
|
@ -222,9 +222,9 @@ filesystem, whose contents Django can access. (Django runs as whatever user
|
|||
your server runs.) Don't put them under your document root, though. You
|
||||
probably shouldn't make them public, just for security's sake.
|
||||
|
||||
Then edit ``TEMPLATE_DIRS`` in your settings file (``settings.py``) to tell
|
||||
Django where it can find templates -- just as you did in the "Customize the
|
||||
admin look and feel" section of Tutorial 2.
|
||||
Then edit ``TEMPLATE_DIRS`` in your ``settings.py`` to tell Django where it can
|
||||
find templates -- just as you did in the "Customize the admin look and feel"
|
||||
section of Tutorial 2.
|
||||
|
||||
When you've done that, create a directory ``polls`` in your template directory.
|
||||
Within that, create a file called ``index.html``. Django requires that
|
||||
|
@ -385,19 +385,19 @@ Take some time to play around with the views and template system. As you edit
|
|||
the URLconf, you may notice there's a fair bit of redundancy in it::
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^polls/$', 'myproject.apps.polls.views.index'),
|
||||
(r'^polls/(?P<poll_id>\d+)/$', 'myproject.apps.polls.views.detail'),
|
||||
(r'^polls/(?P<poll_id>\d+)/results/$', 'myproject.apps.polls.views.results'),
|
||||
(r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.apps.polls.views.vote'),
|
||||
(r'^polls/$', 'myproject.polls.views.index'),
|
||||
(r'^polls/(?P<poll_id>\d+)/$', 'myproject.polls.views.detail'),
|
||||
(r'^polls/(?P<poll_id>\d+)/results/$', 'myproject.polls.views.results'),
|
||||
(r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.polls.views.vote'),
|
||||
)
|
||||
|
||||
Namely, ``myproject.apps.polls.views`` is in every callback.
|
||||
Namely, ``myproject.polls.views`` is in every callback.
|
||||
|
||||
Because this is a common case, the URLconf framework provides a shortcut for
|
||||
common prefixes. You can factor out the common prefixes and add them as the
|
||||
first argument to ``patterns()``, like so::
|
||||
|
||||
urlpatterns = patterns('myproject.apps.polls.views',
|
||||
urlpatterns = patterns('myproject.polls.views',
|
||||
(r'^polls/$', 'index'),
|
||||
(r'^polls/(?P<poll_id>\d+)/$', 'detail'),
|
||||
(r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
|
||||
|
@ -416,18 +416,18 @@ is, each particular app should be transferrable to another Django installation
|
|||
with minimal fuss.
|
||||
|
||||
Our poll app is pretty decoupled at this point, thanks to the strict directory
|
||||
structure that ``django-admin.py startapp`` created, but one part of it is
|
||||
structure that ``python manage.py startapp`` created, but one part of it is
|
||||
coupled to the Django settings: The URLconf.
|
||||
|
||||
We've been editing the URLs in ``myproject/urls.py``, but the URL design of an
|
||||
app is specific to the app, not to the Django installation -- so let's move the
|
||||
URLs within the app directory.
|
||||
|
||||
Copy the file ``myproject/urls.py`` to ``myproject/apps/polls/urls.py``. Then,
|
||||
Copy the file ``myproject/urls.py`` to ``myproject/polls/urls.py``. Then,
|
||||
change ``myproject/urls.py`` to remove the poll-specific URLs and insert an
|
||||
``include()``::
|
||||
|
||||
(r'^polls/', include('myproject.apps.polls.urls')),
|
||||
(r'^polls/', include('myproject.polls.urls')),
|
||||
|
||||
``include()``, simply, references another URLconf. Note that the regular
|
||||
expression doesn't have a ``$`` (end-of-string match character) but has the
|
||||
|
@ -439,14 +439,14 @@ Here's what happens if a user goes to "/polls/34/" in this system:
|
|||
|
||||
* Django will find the match at ``'^polls/'``
|
||||
* It will strip off the matching text (``"polls/"``) and send the remaining
|
||||
text -- ``"34/"`` -- to the 'myproject.apps.polls.urls' urlconf for
|
||||
text -- ``"34/"`` -- to the 'myproject.polls.urls' urlconf for
|
||||
further processing.
|
||||
|
||||
Now that we've decoupled that, we need to decouple the
|
||||
'myproject.apps.polls.urls' urlconf by removing the leading "polls/" from each
|
||||
'myproject.polls.urls' urlconf by removing the leading "polls/" from each
|
||||
line::
|
||||
|
||||
urlpatterns = patterns('myproject.apps.polls.views',
|
||||
urlpatterns = patterns('myproject.polls.views',
|
||||
(r'^$', 'index'),
|
||||
(r'^(?P<poll_id>\d+)/$', 'detail'),
|
||||
(r'^(?P<poll_id>\d+)/results/$', 'results'),
|
||||
|
|
|
@ -44,9 +44,9 @@ Now, let's create a Django view that handles the submitted data and does
|
|||
something with it. Remember, in `Tutorial 3`_, we create a URLconf that
|
||||
included this line::
|
||||
|
||||
(r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.apps.polls.views.vote'),
|
||||
(r'^polls/(?P<poll_id>\d+)/vote/$', 'myproject.polls.views.vote'),
|
||||
|
||||
So let's create a ``vote()`` function in ``myproject/apps/polls/views.py``::
|
||||
So let's create a ``vote()`` function in ``myproject/polls/views.py``::
|
||||
|
||||
from django.core.extensions import get_object_or_404, render_to_response
|
||||
from django.models.polls import choices, polls
|
||||
|
@ -158,7 +158,7 @@ so far::
|
|||
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('myproject.apps.polls.views',
|
||||
urlpatterns = patterns('myproject.polls.views',
|
||||
(r'^$', 'index'),
|
||||
(r'^(?P<poll_id>\d+)/$', 'detail'),
|
||||
(r'^(?P<poll_id>\d+)/results/$', 'results'),
|
||||
|
@ -178,7 +178,7 @@ Change it like so::
|
|||
(r'^$', 'django.views.generic.list_detail.object_list', info_dict),
|
||||
(r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
|
||||
(r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results')),
|
||||
(r'^(?P<poll_id>\d+)/vote/$', 'myproject.apps.polls.views.vote'),
|
||||
(r'^(?P<poll_id>\d+)/vote/$', 'myproject.polls.views.vote'),
|
||||
)
|
||||
|
||||
We're using two generic views here: ``object_list`` and ``object_detail``.
|
||||
|
|
|
@ -51,9 +51,6 @@ algorithm the system follows to determine which Python code to execute:
|
|||
Example
|
||||
=======
|
||||
|
||||
**This syntax is new in the Django development version.** See "Named groups"
|
||||
below if you're using Django 0.90.
|
||||
|
||||
Here's a sample URLconf::
|
||||
|
||||
from django.conf.urls.defaults import *
|
||||
|
@ -110,9 +107,6 @@ to a view. In more advanced usage, it's possible to use *named*
|
|||
regular-expression groups to capture URL bits and pass them as *keyword*
|
||||
arguments to a view.
|
||||
|
||||
(Note that support for non-named regex groups is a new feature in the Django
|
||||
development version. Django 0.90 requires named groups.)
|
||||
|
||||
In Python regular expressions, the syntax for named regular-expression groups
|
||||
is ``(?P<name>pattern)``, where ``name`` is the name of the group and
|
||||
``pattern`` is some pattern to match.
|
||||
|
|
Loading…
Reference in New Issue