-Throughout this reference,
I'll be refer ring to the following Poll application::
+Throughout this reference, 'll refer to the following Poll application::
meta.SlugField('slug', 'slug', unique_for_month='pub_date'),
meta.CharField('question', 'question', maxlength=255),
- module_name = 'choices'
- verbose_name = 'choice'
- db_table = 'poll_choices'
- meta.IntegerField('poll_id', 'poll', rel=meta.ManyToOne(Poll, 'poll', 'id',
- edit_inline=True, edit_inline_type=meta.TABULAR, num_in_admin=10,
+ meta.ForeignKey(Poll, edit_inline=True, edit_inline_type=meta.TABULAR,
+ num_in_admin=10, min_num_in_admin=5),
meta.CharField('choice', 'choice', maxlength=255, core=True),
meta.IntegerField('votes', 'votes', editable=False, default=0),
Each model exposes three basic functions for lookups: ``get_object``,
``get_list``, and ``get_count``. These functions all take the same arguments,
but ``get_object`` assumes that only a single record will be returned (and
-raises an exception if that's not true), ``get_count`` simple returns a count of
-objects matched by the lookup, and ``get_list`` returns the entire list.
+raises ``AssertionError`` if that's not true), ``get_count`` simply returns a
+count of objects matched by the lookup, and ``get_list`` returns a list of objects.
translates (roughly) into the following SQL:
- SELECT * FROM polls WHERE pub_date < NOW();
+ SELECT * FROM polls WHERE pub_date < NOW();
The DB API supports the following lookup types:
iexact Case-insensitive exact match:
``polls.get_list(slug__iexact="foo")`` matches a slug of ``foo``,
- contains Case-sensitive contain
+ contains Case-sensitive contain test:
``polls.get_list(question__contains="spam")`` returns all polls
that contain "spam" in the question.
- icontains Case-insensitive contain
+ icontains Case-insensitive contain
gt Greater than: ``polls.get_list(id__gt=4)``
gte Greater than or equal to
endswith Case-sensitive ends-with
- ``polls.get_list(pub_date__range=(start_date, end_date)``
+ ``polls.get_list(pub_date__range=(start_date, end_date)``
returns all polls with a pub_date between ``start_date``
and ``end_date`` (inclusive).
year For date/datetime fields, exact year match:
-Multiple lookups are of course
allowed, and are translated as " ands"::
+Multiple lookups are of course, and are translated as "::
-retrieves all polls published in Jan. 2005 whose question starts with "Would."
-"Or" lookups are also possible::
+...retrieves all polls published in January 2005 that have a question starting with "Would."
The result set above will be ordered by ``pub_date`` (descending), then
by ``question`` (ascending). Just like in models, the ``order_by`` clause
is a list of ordering tuples where the first element is the field and the
-second is "ASC"
or "DESC" to order ascending or descending. You may also
+second is "ASC" ascending or descending. You also
use the tuple ``(None, "RANDOM")`` to order the result set randomly.
objects where the associated ``Poll`` has a slug of ``eggs``. Multiple levels
-Given an instance of an object, related objects can be looked up directly using
-connivence functions, for example, if ``poll`` is a ``Poll`` instance,
-``poll.get_choice_list()`` will return a list of all associated choices (astute
+Given an instance of an object, related objects can be looked-up directly using
+convenience functions. For example, if ``p`` is a ``Poll`` instance,
+``p.get_choice_list()`` will return a list of all associated choices. Astute
readers will note that this is the same as
oll.id)``, except clearer ).
+``choices.get_list(poll_id__exact=p.id)``, except clearer.
Each type of relationship creates a set of methods on each object in the
These created methods go both ways, so objects that are
+relationship. These s, so objects that are
"related-to" need not explicitly define reverse relationships; that happens
-In each many-to-one relationship the related object will have a
+In each many-to-one relationship the related object will have a
``get_relatedobject()`` method, and the related-to object will have
``get_relatedobject()``, ``get_relatedobject_list()``, and
``get_relatedobject_count()`` methods (the same as the module-level
``get_object()``, ``get_list()``, and ``get_count()`` methods).
-Thus, for the ``Poll`` example at the top, ``Choice`` objects will have a
-``get_poll()`` method, and ``Poll`` objects will have ``get_choice()``,
-``get_choice_list()``, and ``get_choice_count()`` functions.
+In the poll example above, here are the available choice methods on a ``Poll`` object ``p``::
+And a ``Choice`` object ``c`` has the following method::
Many-to-many relations result in the same set of methods as `Many-to-one relations`_,
-except that the ``get_relatedobject
s()`` function on the related object will
+except that the ``get_relatedobject()`` function on the related object will
return a list of instances instead of a single instance. So, if the relationship
-between ``Poll`` and ``Choice`` was many-to-many, ``choice.get_poll
+between ``Poll`` and ``Choice`` was many-to-many, ``choice.get_poll()`` would
Relationships across applications
Relations are the bread and butter of databases, so there's an option to "follow"
all relationships and pre-fill them in a simple cache so that later calls to
-objects with a one-to-many relationship don't have to hit the database. If you pass
-``select_related=True`` to a lookup, this pre-caching of relationships will be performed.
-This results in (sometimes much) larger queries, but it means that later use of
-relationships is much faster.
+objects with a one-to-many relationship don't have to hit the database. Do this by
+passing ``select_related=True`` to a lookup. This results in (sometimes much) larger
+queries, but it means that later use of relationships is much faster.
For example, using the Poll and Choice models from above, if you do the following::
Then subsequent calls to ``c.get_poll()`` won't hit the database.
+Note that ``select_related`` follows foreign keys as far as possible. If you have the
+ class Poll(meta.Model):
+ class Choice(meta.Model):
+ class SingleVote(meta.Model):
+...then a call to ``singlevotes.get_object(id__exact=4, select_related=True)`` will
+cache the related choice *and* the related poll.
+ >>> sv = singlevotes.get_object(id__exact=4, select_related=True)
+ >>> c = sv.get_choice() # Doesn't hit the database.
+ >>> p = c.get_poll() # Doesn't hit the database.
+ >>> sv = singlevotes.get_object(id__exact=4) # Note no "select_related".
+ >>> c = sv.get_choice() # Hits the database.
+ >>> p = c.get_poll() # Hits the database.
which rows are returned. Both ``limit`` and ``offset`` should be integers which
will be directly passed to the SQL ``LIMIT``/``OFFSET`` commands.
-If ``distinct`` is True, only distinct rows will be returned (this is equivalent
-to a ``SELECT DISTINCT`` SQL clause).
+If ``distinct`` is True, only distinct rows will be returned. This is equivalent
+to a ``SELECT DISTINCT`` SQL clause.
There are a few other ways of more directly controlling the generated SQL
for the lookup. Note that by definition these extra lookups may not be
-portable to different database engines (since you're explicitly writing
-SQL code) and should be avoided where ever possible.:
+portable to different database engines (because you're explicitly writing
+SQL code) and should be avoided if possible.:
The ``select`` keyword allows you to select extra fields. This should be a
-dict mapping field names to a SQL clause to use for that field. For example::
+dictionary mapping attribute names to a SQL clause to use to calculate that
+attribute. For example::
: 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id'
+ 'choice_count': 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id'
-Each of the resulting ``Poll`` objects will have an extra ``choice_count`` with
-a count of associated ``Choice`` objects. Note that the parenthesis required by
+Each of the resulting ``Poll`` objects will have an extra attribute, ``choice_count``,
+an integer count of associated ``Choice`` objects. Note that the parenthesis required by
most database engines around sub-selects are not required in Django's ``select``
If you need to explicitly pass extra ``WHERE`` clauses -- perhaps to perform
-non-explicit joins -- use the ``where`` keyword.
. If you need to
+non-explicit joins -- use the ``where`` keyword. If you need to
join other tables into your query, you can pass their names to ``tables``.
+``where`` and ``tables`` both take a list of strings. All ``where`` parameters
+are "AND"ed to any other search criteria.
+ polls.get_list(question__startswith='Who', where=['id IN (3, 4, 5, 20)'])
+...translates (roughly) into the following SQL:
+ SELECT * FROM polls_polls WHERE question LIKE 'Who%' AND id IN (3, 4, 5, 20);