Made some changes to db-api docs
git-svn-id: http://code.djangoproject.com/svn/django/trunk@32 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
fda1f68492
commit
26c6566215
130
docs/db-api.txt
130
docs/db-api.txt
|
@ -4,12 +4,9 @@ Database API reference
|
||||||
|
|
||||||
XXX INTRO HERE XXX
|
XXX INTRO HERE XXX
|
||||||
|
|
||||||
Throughout this reference, I'll be referring to the following Poll application::
|
Throughout this reference, we'll refer to the following Poll application::
|
||||||
|
|
||||||
class Poll(meta.Model):
|
class Poll(meta.Model):
|
||||||
module_name = 'polls'
|
|
||||||
verbose_name = 'poll'
|
|
||||||
db_table = 'polls'
|
|
||||||
fields = (
|
fields = (
|
||||||
meta.SlugField('slug', 'slug', unique_for_month='pub_date'),
|
meta.SlugField('slug', 'slug', unique_for_month='pub_date'),
|
||||||
meta.CharField('question', 'question', maxlength=255),
|
meta.CharField('question', 'question', maxlength=255),
|
||||||
|
@ -18,13 +15,9 @@ Throughout this reference, I'll be referring to the following Poll application::
|
||||||
)
|
)
|
||||||
|
|
||||||
class Choice(meta.Model):
|
class Choice(meta.Model):
|
||||||
module_name = 'choices'
|
|
||||||
verbose_name = 'choice'
|
|
||||||
db_table = 'poll_choices'
|
|
||||||
fields = (
|
fields = (
|
||||||
meta.IntegerField('poll_id', 'poll', rel=meta.ManyToOne(Poll, 'poll', 'id',
|
meta.ForeignKey(Poll, edit_inline=True, edit_inline_type=meta.TABULAR,
|
||||||
edit_inline=True, edit_inline_type=meta.TABULAR, num_in_admin=10,
|
num_in_admin=10, min_num_in_admin=5),
|
||||||
min_num_in_admin=5)),
|
|
||||||
meta.CharField('choice', 'choice', maxlength=255, core=True),
|
meta.CharField('choice', 'choice', maxlength=255, core=True),
|
||||||
meta.IntegerField('votes', 'votes', editable=False, default=0),
|
meta.IntegerField('votes', 'votes', editable=False, default=0),
|
||||||
)
|
)
|
||||||
|
@ -35,8 +28,8 @@ Basic lookup functions
|
||||||
Each model exposes three basic functions for lookups: ``get_object``,
|
Each model exposes three basic functions for lookups: ``get_object``,
|
||||||
``get_list``, and ``get_count``. These functions all take the same arguments,
|
``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
|
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
|
raises ``AssertionError`` if that's not true), ``get_count`` simply returns a
|
||||||
objects matched by the lookup, and ``get_list`` returns the entire list.
|
count of objects matched by the lookup, and ``get_list`` returns a list of objects.
|
||||||
|
|
||||||
Field lookups
|
Field lookups
|
||||||
=============
|
=============
|
||||||
|
@ -48,7 +41,7 @@ double-underscore). For example::
|
||||||
|
|
||||||
translates (roughly) into the following SQL:
|
translates (roughly) into the following SQL:
|
||||||
|
|
||||||
SELECT * FROM polls WHERE pub_date < NOW();
|
SELECT * FROM polls_polls WHERE pub_date < NOW();
|
||||||
|
|
||||||
The DB API supports the following lookup types:
|
The DB API supports the following lookup types:
|
||||||
|
|
||||||
|
@ -59,10 +52,10 @@ The DB API supports the following lookup types:
|
||||||
iexact Case-insensitive exact match:
|
iexact Case-insensitive exact match:
|
||||||
``polls.get_list(slug__iexact="foo")`` matches a slug of ``foo``,
|
``polls.get_list(slug__iexact="foo")`` matches a slug of ``foo``,
|
||||||
``FOO``, ``fOo``, etc.
|
``FOO``, ``fOo``, etc.
|
||||||
contains Case-sensitive contains test:
|
contains Case-sensitive containment test:
|
||||||
``polls.get_list(question__contains="spam")`` returns all polls
|
``polls.get_list(question__contains="spam")`` returns all polls
|
||||||
that contain "spam" in the question.
|
that contain "spam" in the question.
|
||||||
icontains Case-insensitive contains
|
icontains Case-insensitive containment test
|
||||||
gt Greater than: ``polls.get_list(id__gt=4)``
|
gt Greater than: ``polls.get_list(id__gt=4)``
|
||||||
gte Greater than or equal to
|
gte Greater than or equal to
|
||||||
lt Less than
|
lt Less than
|
||||||
|
@ -71,7 +64,7 @@ The DB API supports the following lookup types:
|
||||||
``polls.get_list(question_startswith="Would")``
|
``polls.get_list(question_startswith="Would")``
|
||||||
endswith Case-sensitive ends-with
|
endswith Case-sensitive ends-with
|
||||||
range Range test:
|
range Range test:
|
||||||
``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``
|
returns all polls with a pub_date between ``start_date``
|
||||||
and ``end_date`` (inclusive).
|
and ``end_date`` (inclusive).
|
||||||
year For date/datetime fields, exact year match:
|
year For date/datetime fields, exact year match:
|
||||||
|
@ -82,7 +75,7 @@ The DB API supports the following lookup types:
|
||||||
``polls.get_list(expire_date__isnull=True)``.
|
``polls.get_list(expire_date__isnull=True)``.
|
||||||
========== ==============================================================
|
========== ==============================================================
|
||||||
|
|
||||||
Multiple lookups are of course allowed, and are translated as "ands"::
|
Multiple lookups are allowed, of course, and are translated as "AND"s::
|
||||||
|
|
||||||
polls.get_list(
|
polls.get_list(
|
||||||
pub_date__year=2005,
|
pub_date__year=2005,
|
||||||
|
@ -90,11 +83,7 @@ Multiple lookups are of course allowed, and are translated as "ands"::
|
||||||
question__startswith="Would",
|
question__startswith="Would",
|
||||||
)
|
)
|
||||||
|
|
||||||
retrieves all polls published in Jan. 2005 whose question starts with "Would."
|
...retrieves all polls published in January 2005 that have a question starting with "Would."
|
||||||
|
|
||||||
"Or" lookups are also possible::
|
|
||||||
|
|
||||||
XXX FIXME XXX
|
|
||||||
|
|
||||||
Ordering
|
Ordering
|
||||||
========
|
========
|
||||||
|
@ -112,7 +101,7 @@ provided by the ``order_by`` argument to a lookup::
|
||||||
The result set above will be ordered by ``pub_date`` (descending), then
|
The result set above will be ordered by ``pub_date`` (descending), then
|
||||||
by ``question`` (ascending). Just like in models, the ``order_by`` clause
|
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
|
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 "DESC" (descending). You can also
|
||||||
use the tuple ``(None, "RANDOM")`` to order the result set randomly.
|
use the tuple ``(None, "RANDOM")`` to order the result set randomly.
|
||||||
|
|
||||||
Relationships (joins)
|
Relationships (joins)
|
||||||
|
@ -123,14 +112,14 @@ Joins may implicitly be performed by following relationships:
|
||||||
objects where the associated ``Poll`` has a slug of ``eggs``. Multiple levels
|
objects where the associated ``Poll`` has a slug of ``eggs``. Multiple levels
|
||||||
of joins are allowed.
|
of joins are allowed.
|
||||||
|
|
||||||
Given an instance of an object, related objects can be looked up directly using
|
Given an instance of an object, related objects can be looked-up directly using
|
||||||
connivence functions, for example, if ``poll`` is a ``Poll`` instance,
|
convenience functions. For example, if ``p`` is a ``Poll`` instance,
|
||||||
``poll.get_choice_list()`` will return a list of all associated choices (astute
|
``p.get_choice_list()`` will return a list of all associated choices. Astute
|
||||||
readers will note that this is the same as
|
readers will note that this is the same as
|
||||||
``choices.get_list(poll_id__exact=poll.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
|
Each type of relationship creates a set of methods on each object in the
|
||||||
relationship. These created methods go both ways, so objects that are
|
relationship. These methods are created in both directions, so objects that are
|
||||||
"related-to" need not explicitly define reverse relationships; that happens
|
"related-to" need not explicitly define reverse relationships; that happens
|
||||||
automatically.
|
automatically.
|
||||||
|
|
||||||
|
@ -141,7 +130,6 @@ Each object in a one-to-one relationship will have a ``get_relatedobject()``
|
||||||
method. For example::
|
method. For example::
|
||||||
|
|
||||||
class Place(meta.Model):
|
class Place(meta.Model):
|
||||||
...
|
|
||||||
fields = (
|
fields = (
|
||||||
...
|
...
|
||||||
)
|
)
|
||||||
|
@ -160,23 +148,29 @@ and each ``Restaurant`` will have a ``get_place()`` method.
|
||||||
Many-to-one relations
|
Many-to-one relations
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
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()`` method, and the related-to object will have
|
||||||
``get_relatedobject()``, ``get_relatedobject_list()``, and
|
``get_relatedobject()``, ``get_relatedobject_list()``, and
|
||||||
``get_relatedobject_count()`` methods (the same as the module-level
|
``get_relatedobject_count()`` methods (the same as the module-level
|
||||||
``get_object()``, ``get_list()``, and ``get_count()`` methods).
|
``get_object()``, ``get_list()``, and ``get_count()`` methods).
|
||||||
|
|
||||||
Thus, for the ``Poll`` example at the top, ``Choice`` objects will have a
|
In the poll example above, here are the available choice methods on a ``Poll`` object ``p``::
|
||||||
``get_poll()`` method, and ``Poll`` objects will have ``get_choice()``,
|
|
||||||
``get_choice_list()``, and ``get_choice_count()`` functions.
|
p.get_choice()
|
||||||
|
p.get_choice_list()
|
||||||
|
p.get_choice_count()
|
||||||
|
|
||||||
|
And a ``Choice`` object ``c`` has the following method::
|
||||||
|
|
||||||
|
c.get_poll()
|
||||||
|
|
||||||
Many-to-many relations
|
Many-to-many relations
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Many-to-many relations result in the same set of methods as `Many-to-one relations`_,
|
Many-to-many relations result in the same set of methods as `Many-to-one relations`_,
|
||||||
except that the ``get_relatedobjects()`` function on the related object will
|
except that the ``get_relatedobject_list()`` function on the related object will
|
||||||
return a list of instances instead of a single instance. So, if the relationship
|
return a list of instances instead of a single instance. So, if the relationship
|
||||||
between ``Poll`` and ``Choice`` was many-to-many, ``choice.get_polls()`` would
|
between ``Poll`` and ``Choice`` was many-to-many, ``choice.get_poll_list()`` would
|
||||||
return a list.
|
return a list.
|
||||||
|
|
||||||
Relationships across applications
|
Relationships across applications
|
||||||
|
@ -192,10 +186,9 @@ Selecting related objects
|
||||||
|
|
||||||
Relations are the bread and butter of databases, so there's an option to "follow"
|
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
|
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
|
objects with a one-to-many relationship don't have to hit the database. Do this by
|
||||||
``select_related=True`` to a lookup, this pre-caching of relationships will be performed.
|
passing ``select_related=True`` to a lookup. This results in (sometimes much) larger
|
||||||
This results in (sometimes much) larger queries, but it means that later use of
|
queries, but it means that later use of relationships is much faster.
|
||||||
relationships is much faster.
|
|
||||||
|
|
||||||
For example, using the Poll and Choice models from above, if you do the following::
|
For example, using the Poll and Choice models from above, if you do the following::
|
||||||
|
|
||||||
|
@ -203,6 +196,35 @@ For example, using the Poll and Choice models from above, if you do the followin
|
||||||
|
|
||||||
Then subsequent calls to ``c.get_poll()`` won't hit the database.
|
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
|
||||||
|
following models...
|
||||||
|
|
||||||
|
class Poll(meta.Model):
|
||||||
|
...
|
||||||
|
|
||||||
|
class Choice(meta.Model):
|
||||||
|
fields = (
|
||||||
|
meta.ForeignKey(Poll),
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
class SingleVote(meta.Model):
|
||||||
|
fields = (
|
||||||
|
meta.ForeignKey(Choice),
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
...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.
|
||||||
|
|
||||||
Limiting selected rows
|
Limiting selected rows
|
||||||
======================
|
======================
|
||||||
|
|
||||||
|
@ -210,16 +232,16 @@ The ``limit``, ``offset``, and ``distinct`` keywords can be used to control
|
||||||
which rows are returned. Both ``limit`` and ``offset`` should be integers which
|
which rows are returned. Both ``limit`` and ``offset`` should be integers which
|
||||||
will be directly passed to the SQL ``LIMIT``/``OFFSET`` commands.
|
will be directly passed to the SQL ``LIMIT``/``OFFSET`` commands.
|
||||||
|
|
||||||
If ``distinct`` is True, only distinct rows will be returned (this is equivalent
|
If ``distinct`` is True, only distinct rows will be returned. This is equivalent
|
||||||
to a ``SELECT DISTINCT`` SQL clause).
|
to a ``SELECT DISTINCT`` SQL clause.
|
||||||
|
|
||||||
Other lookup options
|
Other lookup options
|
||||||
====================
|
====================
|
||||||
|
|
||||||
There are a few other ways of more directly controlling the generated SQL
|
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
|
for the lookup. Note that by definition these extra lookups may not be
|
||||||
portable to different database engines (since you're explicitly writing
|
portable to different database engines (because you're explicitly writing
|
||||||
SQL code) and should be avoided where ever possible.:
|
SQL code) and should be avoided if possible.:
|
||||||
|
|
||||||
``params``
|
``params``
|
||||||
----------
|
----------
|
||||||
|
@ -233,16 +255,17 @@ parameters to be substituted.
|
||||||
----------
|
----------
|
||||||
|
|
||||||
The ``select`` keyword allows you to select extra fields. This should be a
|
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::
|
||||||
|
|
||||||
polls.get_list(
|
polls.get_list(
|
||||||
select={
|
select={
|
||||||
'choice_count' : '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
|
Each of the resulting ``Poll`` objects will have an extra attribute, ``choice_count``,
|
||||||
a count of associated ``Choice`` objects. Note that the parenthesis required by
|
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``
|
most database engines around sub-selects are not required in Django's ``select``
|
||||||
clauses.
|
clauses.
|
||||||
|
|
||||||
|
@ -250,9 +273,20 @@ clauses.
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
If you need to explicitly pass extra ``WHERE`` clauses -- perhaps to perform
|
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``.
|
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.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
Creating new objects
|
Creating new objects
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue