Proofread docs/db-api.txt
git-svn-id: http://code.djangoproject.com/svn/django/trunk@2820 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c62a014049
commit
227d48af1c
424
docs/db-api.txt
424
docs/db-api.txt
|
@ -1032,6 +1032,30 @@ equivalent::
|
||||||
Entry.objects.filter(blog__id__exact=3)
|
Entry.objects.filter(blog__id__exact=3)
|
||||||
Entry.objects.filter(blog__pk=3)
|
Entry.objects.filter(blog__pk=3)
|
||||||
|
|
||||||
|
Lookups that span relationships
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Django offers a powerful and intuitive way to "follow" relationships in
|
||||||
|
lookups, taking care of the SQL ``JOIN``s for you automatically, behind the
|
||||||
|
scenes. To span a relationship, just use the field name of related fields
|
||||||
|
across models, separated by double underscores, until you get to the field you
|
||||||
|
want.
|
||||||
|
|
||||||
|
This example retrieves all ``Entry`` objects with a ``Blog`` whose ``name``
|
||||||
|
is ``'Beatles Blog'``::
|
||||||
|
|
||||||
|
Entry.objects.filter(blog__name__exact='Beatles Blog')
|
||||||
|
|
||||||
|
This spanning can be as deep as you'd like.
|
||||||
|
|
||||||
|
It works backwards, too. To refer to a "reverse" relationship, just use the
|
||||||
|
lowercase name of the model.
|
||||||
|
|
||||||
|
This example retrieves all ``Blog`` objects who have at least one ``Entry``
|
||||||
|
whose ``headline`` contains ``'Lennon'``::
|
||||||
|
|
||||||
|
Blog.objects.filter(entry__headline__contains='Lennon')
|
||||||
|
|
||||||
Escaping parenthesis and underscores in LIKE statements
|
Escaping parenthesis and underscores in LIKE statements
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -1106,37 +1130,41 @@ primary key field is called ``name``, these two statements are equivalent::
|
||||||
some_obj == other_obj
|
some_obj == other_obj
|
||||||
some_obj.name == other_obj.name
|
some_obj.name == other_obj.name
|
||||||
|
|
||||||
OR lookups
|
Complex lookups with Q objects
|
||||||
==========
|
==============================
|
||||||
|
|
||||||
Keyword argument queries are "AND"ed together. If you have more
|
Keyword argument queries -- in ``filter()``, etc. -- are "AND"ed together. If
|
||||||
complex query requirements (for example, you need to include an ``OR``
|
you need to execute more more complex queries (for example, queries with ``OR``
|
||||||
statement in your query), you need to use ``Q`` objects.
|
statements), you can use ``Q`` objects.
|
||||||
|
|
||||||
A ``Q`` object (``django.db.models.Q``) is an object used to encapsulate a
|
A ``Q`` object (``django.db.models.Q``) is an object used to encapsulate a
|
||||||
collection of keyword arguments. These keyword arguments are specified in
|
collection of keyword arguments. These keyword arguments are specified as in
|
||||||
the same way as keyword arguments to the basic lookup functions like get()
|
"Field lookups" above.
|
||||||
and filter(). For example::
|
|
||||||
|
For example, this ``Q`` object encapsulates a single ``LIKE`` query::
|
||||||
|
|
||||||
Q(question__startswith='What')
|
Q(question__startswith='What')
|
||||||
|
|
||||||
is a ``Q`` object encapsulating a single ``LIKE`` query. ``Q`` objects can be
|
``Q`` objects can be combined using the ``&`` and ``|`` operators. When an
|
||||||
combined using the ``&`` and ``|`` operators. When an operator is used on two
|
operator is used on two ``Q`` objects, it yields a new ``Q`` object.
|
||||||
``Q`` objects, it yields a new ``Q`` object. For example the statement::
|
|
||||||
|
For example, this statement yields a single ``Q`` object that represents the
|
||||||
|
"OR" of two ``"question__startswith"`` queries::
|
||||||
|
|
||||||
Q(question__startswith='Who') | Q(question__startswith='What')
|
Q(question__startswith='Who') | Q(question__startswith='What')
|
||||||
|
|
||||||
... yields a single ``Q`` object that represents the "OR" of two
|
This is equivalent to the following SQL ``WHERE`` clause::
|
||||||
"question__startswith" queries, equivalent to the SQL WHERE clause::
|
|
||||||
|
|
||||||
... WHERE question LIKE 'Who%' OR question LIKE 'What%'
|
WHERE question LIKE 'Who%' OR question LIKE 'What%'
|
||||||
|
|
||||||
You can compose statements of arbitrary complexity by combining ``Q`` objects
|
You can compose statements of arbitrary complexity by combining ``Q`` objects
|
||||||
with the ``&`` and ``|`` operators. Parenthetical grouping can also be used.
|
with the ``&`` and ``|`` operators. You can also use parenthetical grouping.
|
||||||
|
|
||||||
One or more ``Q`` objects can then provided as arguments to the lookup
|
Each lookup function that takes keyword-arguments (e.g. ``filter()``,
|
||||||
functions. If multiple ``Q`` object arguments are provided to a lookup
|
``exclude()``, ``get()``) can also be passed one or more ``Q`` objects as
|
||||||
function, they will be "AND"ed together. For example::
|
positional (not-named) arguments. If you provide multiple ``Q`` object
|
||||||
|
arguments to a lookup function, the arguments will be "AND"ed together. For
|
||||||
|
example::
|
||||||
|
|
||||||
Poll.objects.get(
|
Poll.objects.get(
|
||||||
Q(question__startswith='Who'),
|
Q(question__startswith='Who'),
|
||||||
|
@ -1148,11 +1176,10 @@ function, they will be "AND"ed together. For example::
|
||||||
SELECT * from polls WHERE question LIKE 'Who%'
|
SELECT * from polls WHERE question LIKE 'Who%'
|
||||||
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
|
AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
|
||||||
|
|
||||||
If necessary, lookup functions can mix the use of ``Q`` objects and keyword
|
Lookup functions can mix the use of ``Q`` objects and keyword arguments. All
|
||||||
arguments. All arguments provided to a lookup function (be they keyword
|
arguments provided to a lookup function (be they keyword arguments or ``Q``
|
||||||
argument or ``Q`` object) are "AND"ed together. However, if a ``Q`` object is
|
objects) are "AND"ed together. However, if a ``Q`` object is provided, it must
|
||||||
provided, it must precede the definition of any keyword arguments. For
|
precede the definition of any keyword arguments. For example::
|
||||||
example::
|
|
||||||
|
|
||||||
Poll.objects.get(
|
Poll.objects.get(
|
||||||
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
|
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
|
||||||
|
@ -1167,193 +1194,242 @@ example::
|
||||||
|
|
||||||
... would not be valid.
|
... would not be valid.
|
||||||
|
|
||||||
A ``Q`` objects can also be provided to the ``complex`` keyword argument. For example::
|
|
||||||
|
|
||||||
Poll.objects.get(
|
|
||||||
complex=Q(question__startswith='Who') &
|
|
||||||
(Q(pub_date=date(2005, 5, 2)) |
|
|
||||||
Q(pub_date=date(2005, 5, 6))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
See the `OR lookups examples page`_ for more examples.
|
See the `OR lookups examples page`_ for more examples.
|
||||||
|
|
||||||
.. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/
|
.. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/
|
||||||
|
|
||||||
|
Related objects
|
||||||
|
===============
|
||||||
|
|
||||||
Relationships (joins)
|
When you define a relationship in a model (i.e., a ``ForeignKey``,
|
||||||
=====================
|
``OneToOneField``, or ``ManyToManyField``), instances of that model will have
|
||||||
|
a convenient API to access the related object(s).
|
||||||
|
|
||||||
When you define a relationship in a model (i.e., a ForeignKey,
|
Using the models at the top of this page, for example, an ``Entry`` object ``e``
|
||||||
OneToOneField, or ManyToManyField), Django uses the name of the
|
can get its associated ``Blog`` object by accessing the ``blog`` attribute:
|
||||||
relationship to add a descriptor_ on every instance of the model.
|
``e.blog``.
|
||||||
This descriptor behaves just like a normal attribute, providing
|
|
||||||
access to the related object or objects. For example,
|
|
||||||
``mychoice.poll`` will return the poll object associated with a specific
|
|
||||||
instance of ``Choice``.
|
|
||||||
|
|
||||||
.. _descriptor: http://users.rcn.com/python/download/Descriptor.htm
|
(Behind the scenes, this functionality is implemented by Python descriptors_.
|
||||||
|
This shouldn't really matter to you, but we point it out here for the curious.)
|
||||||
|
|
||||||
Django also adds a descriptor for the 'other' side of the relationship -
|
Django also creates API accessors for the "other" side of the relationship --
|
||||||
the link from the related model to the model that defines the relationship.
|
the link from the related model to the model that defines the relationship.
|
||||||
Since the related model has no explicit reference to the source model,
|
For example, a ``Blog`` object ``b`` has access to a list of all related
|
||||||
Django will automatically derive a name for this descriptor. The name that
|
``Entry`` objects via the ``entry_set`` attribute: ``b.entry_set.all()``.
|
||||||
Django chooses depends on the type of relation that is represented. However,
|
|
||||||
if the definition of the relation has a `related_name` parameter, Django
|
|
||||||
will use this name in preference to deriving a name.
|
|
||||||
|
|
||||||
There are two types of descriptor that can be employed: Single Object
|
All examples in this section use the sample ``Blog``, ``Author`` and ``Entry``
|
||||||
Descriptors and Object Set Descriptors. The following table describes
|
models defined at the top of this page.
|
||||||
when each descriptor type is employed. The local model is the model on
|
|
||||||
which the relation is defined; the related model is the model referred
|
|
||||||
to by the relation.
|
|
||||||
|
|
||||||
=============== ============= =============
|
.. _descriptors: http://users.rcn.com/python/download/Descriptor.htm
|
||||||
Relation Type Local Model Related Model
|
|
||||||
=============== ============= =============
|
|
||||||
OneToOneField Single Object Single Object
|
|
||||||
|
|
||||||
ForeignKey Single Object Object Set
|
One-to-many relationships
|
||||||
|
-------------------------
|
||||||
|
|
||||||
ManyToManyField Object Set Object Set
|
Forward
|
||||||
=============== ============= =============
|
~~~~~~~
|
||||||
|
|
||||||
Single object descriptor
|
If a model has a ``ForeignKey``, instances of that model will have access to
|
||||||
------------------------
|
the related (foreign) object via a simple attribute of the model.
|
||||||
|
|
||||||
If the related object is a single object, the descriptor acts
|
Example::
|
||||||
just as if the related object were an attribute::
|
|
||||||
|
|
||||||
# Obtain the existing poll
|
e = Entry.objects.get(id=2)
|
||||||
old_poll = mychoice.poll
|
e.blog # Returns the related Blog object.
|
||||||
# Set a new poll
|
|
||||||
mychoice.poll = new_poll
|
|
||||||
# Save the change
|
|
||||||
mychoice.save()
|
|
||||||
|
|
||||||
Whenever a change is made to a Single Object Descriptor, save()
|
You can get and set via a foreign-key attribute. As you may expect, changes to
|
||||||
must be called to commit the change to the database.
|
the foreign key aren't saved to the database until you call ``save()``.
|
||||||
|
Example::
|
||||||
|
|
||||||
If no `related_name` parameter is defined, Django will use the
|
e = Entry.objects.get(id=2)
|
||||||
lower case version of the source model name as the name for the
|
e.blog = some_blog
|
||||||
related descriptor. For example, if the ``Choice`` model had
|
e.save()
|
||||||
a field::
|
|
||||||
|
|
||||||
coordinator = models.OneToOneField(User)
|
If a ``ForeignKey`` field has ``null=True`` set (i.e., it allows ``NULL``
|
||||||
|
values), you can assign ``None`` to it. Example::
|
||||||
|
|
||||||
... instances of the model ``User`` would be able to call:
|
e = Entry.objects.get(id=2)
|
||||||
|
e.blog = None
|
||||||
|
e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
|
||||||
|
|
||||||
old_choice = myuser.choice
|
Forward access to one-to-many relationships is cached the first time the
|
||||||
myuser.choice = new_choice
|
related object is accessed. Subsequent accesses to the foreign key on the same
|
||||||
|
object instance are cached. Example::
|
||||||
|
|
||||||
By default, relations do not allow values of None; if you attempt
|
e = Entry.objects.get(id=2)
|
||||||
to assign None to a Single Object Descriptor, an AttributeError
|
print e.blog # Hits the database to retrieve the associated Blog.
|
||||||
will be thrown. However, if the relation has 'null=True' set
|
print e.blog # Doesn't hit the database; uses cached version.
|
||||||
(i.e., the database will allow NULLs for the relation), None can
|
|
||||||
be assigned and returned by the descriptor to represent empty
|
|
||||||
relations.
|
|
||||||
|
|
||||||
Access to Single Object Descriptors is cached. The first time
|
Note that the ``select_related()`` ``QuerySet`` method recursively prepopulates
|
||||||
a descriptor on an instance is accessed, the database will be
|
the cache of all one-to-many relationships ahead of time. Example::
|
||||||
queried, and the result stored. Subsequent attempts to access
|
|
||||||
the descriptor on the same instance will use the cached value.
|
|
||||||
|
|
||||||
Object set descriptor
|
e = Entry.objects.select_related().get(id=2)
|
||||||
---------------------
|
print e.blog # Doesn't hit the database; uses cached version.
|
||||||
|
print e.blog # Doesn't hit the database; uses cached version.
|
||||||
|
|
||||||
An Object Set Descriptor acts just like the Manager - as an initial Query
|
``select_related()`` is documented in the "QuerySet methods that return new
|
||||||
Set describing the set of objects related to an instance. As such, any
|
QuerySets" section above.
|
||||||
query refining technique (filter, exclude, etc) can be used on the Object
|
|
||||||
Set descriptor. This also means that Object Set Descriptor cannot be evaluated
|
|
||||||
directly - the ``all()`` method must be used to produce a Query Set that
|
|
||||||
can be evaluated.
|
|
||||||
|
|
||||||
If no ``related_name`` parameter is defined, Django will use the lower case
|
Backward
|
||||||
version of the source model name appended with `_set` as the name for the
|
~~~~~~~~
|
||||||
related descriptor. For example, every ``Poll`` object has a ``choice_set``
|
|
||||||
descriptor.
|
|
||||||
|
|
||||||
The Object Set Descriptor has utility methods to add objects to the
|
If a model has a ``ForeignKey``, instances of the foreign-key model will have
|
||||||
related object set:
|
access to a ``Manager`` that returns all instances of the first model. By
|
||||||
|
default, this ``Manager`` is named ``FOO_set``, where ``FOO`` is the source
|
||||||
|
model name, lowercased. This ``Manager`` returns ``QuerySets``, which can be
|
||||||
|
filtered and manipulated as described in the "Retrieving objects" section
|
||||||
|
above.
|
||||||
|
|
||||||
``add(obj1, obj2, ...)``
|
Example::
|
||||||
Add the specified objects to the related object set.
|
|
||||||
|
|
||||||
``create(\**kwargs)``
|
b = Blog.objects.get(id=1)
|
||||||
Create a new object, and put it in the related object set. See
|
b.entry_set.all() # Returns all Entry objects related to Blog.
|
||||||
_`Creating new objects`
|
|
||||||
|
|
||||||
The Object Set Descriptor may also have utility methods to remove objects
|
# b.entry_set is a Manager that returns QuerySets.
|
||||||
from the related object set:
|
b.entry_set.filter(headline__contains='Lennon')
|
||||||
|
b.entry_set.count()
|
||||||
|
|
||||||
``remove(obj1, obj2, ...)``
|
You can override the ``FOO_set`` name by setting the ``related_name``
|
||||||
Remove the specified objects from the related object set.
|
parameter in the ``ForeignKey()`` definition. For example, if the ``Entry``
|
||||||
|
model was altered to ``blog = ForeignKey(Blog, related_name='entries')``, the
|
||||||
|
above example code would look like this::
|
||||||
|
|
||||||
``clear()``
|
b = Blog.objects.get(id=1)
|
||||||
Remove all objects from the related object set.
|
b.entries.all() # Returns all Entry objects related to Blog.
|
||||||
|
|
||||||
These two removal methods will not exist on ForeignKeys where ``Null=False``
|
# b.entries is a Manager that returns QuerySets.
|
||||||
(such as in the Poll example). This is to prevent database inconsistency - if
|
b.entries.filter(headline__contains='Lennon')
|
||||||
the related field cannot be set to None, then an object cannot be removed
|
b.entries.count()
|
||||||
from one relation without adding it to another.
|
|
||||||
|
|
||||||
The members of a related object set can be assigned from any iterable object.
|
You cannot access a reverse ``ForeignKey`` ``Manager`` from the class; it must
|
||||||
For example::
|
be accessed from an instance. Example::
|
||||||
|
|
||||||
mypoll.choice_set = [choice1, choice2]
|
Blog.entry_set # Raises AttributeError: "Manager must be accessed via instance".
|
||||||
|
|
||||||
If the ``clear()`` method is available, any pre-existing objects will be removed
|
In addition to the ``QuerySet`` methods defined in "Retrieving objects" above,
|
||||||
from the Object Set before all objects in the iterable (in this case, a list)
|
the ``ForeignKey`` ``Manager`` has these additional methods:
|
||||||
are added to the choice set. If the ``clear()`` method is not available, all
|
|
||||||
objects in the iterable will be added without removing any existing elements.
|
|
||||||
|
|
||||||
Each of these operations on the Object Set Descriptor has immediate effect
|
* ``add(obj1, obj2, ...)``: Adds the specified model objects to the related
|
||||||
on the database - every add, create and remove is immediately and
|
object set.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
b = Blog.objects.get(id=1)
|
||||||
|
e = Entry.objects.get(id=234)
|
||||||
|
b.entry_set.add(e) # Associates Entry e with Blog b.
|
||||||
|
|
||||||
|
* ``create(**kwargs)``: Creates a new object, saves it and puts it in the
|
||||||
|
related object set. Returns the newly created object.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
b = Blog.objects.get(id=1)
|
||||||
|
e = b.entry_set.create(headline='Hello', body_text='Hi', pub_date=datetime.date(2005, 1, 1))
|
||||||
|
# No need to call e.save() at this point -- it's already been saved.
|
||||||
|
|
||||||
|
This is equivalent to (but much simpler than)::
|
||||||
|
|
||||||
|
b = Blog.objects.get(id=1)
|
||||||
|
e = Entry(blog=b, headline='Hello', body_text='Hi', pub_date=datetime.date(2005, 1, 1))
|
||||||
|
e.save()
|
||||||
|
|
||||||
|
Note that there's no need to specify the keyword argument of the model
|
||||||
|
that defines the relationship. In the above example, we don't pass the
|
||||||
|
parameter ``blog`` to ``create()``. Django figures out that the new
|
||||||
|
``Entry`` object's ``blog`` field should be set to ``b``.
|
||||||
|
|
||||||
|
* ``remove(obj1, obj2, ...)``: Removes the specified model objects from the
|
||||||
|
related object set.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
b = Blog.objects.get(id=1)
|
||||||
|
e = Entry.objects.get(id=234)
|
||||||
|
b.entry_set.remove(e) # Disassociates Entry e from Blog b.
|
||||||
|
|
||||||
|
In order to prevent database inconsistency, this method only exists on
|
||||||
|
``ForeignKey``s where ``null=True``. If the related field can't be set to
|
||||||
|
``None`` (``NULL``), then an object can't be removed from a relation
|
||||||
|
without being added to another. In the above example, removing ``e`` from
|
||||||
|
``b.entry_set()`` is equivalent to doing ``e.blog = None``, and because
|
||||||
|
the ``blog`` ``ForeignKey`` doesn't have ``null=True``, this is invalid.
|
||||||
|
|
||||||
|
* ``clear()``: Removes all objects from the related object set.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
b = Blog.objects.get(id=1)
|
||||||
|
b.entry_set.clear()
|
||||||
|
|
||||||
|
Note this doesn't delete the related objects -- it just disassociates
|
||||||
|
them.
|
||||||
|
|
||||||
|
Just like ``remove()``, ``clear()`` is only available on ``ForeignKey``s
|
||||||
|
where ``null=True``.
|
||||||
|
|
||||||
|
To assign the members of a related set in one fell swoop, just assign to it
|
||||||
|
from any iterable object. Example::
|
||||||
|
|
||||||
|
b = Blog.objects.get(id=1)
|
||||||
|
b.entry_set = [e1, e2]
|
||||||
|
|
||||||
|
If the ``clear()`` method is available, any pre-existing objects will be
|
||||||
|
removed from the ``entry_set`` before all objects in the iterable (in this
|
||||||
|
case, a list) are added to the set. If the ``clear()`` method is *not*
|
||||||
|
available, all objects in the iterable will be added without removing any
|
||||||
|
existing elements.
|
||||||
|
|
||||||
|
Each "reverse" operation described in this section has an immediate effect on
|
||||||
|
the database. Every addition, creation and deletion is immediately and
|
||||||
automatically saved to the database.
|
automatically saved to the database.
|
||||||
|
|
||||||
Relationships and queries
|
Many-to-many relationships
|
||||||
=========================
|
--------------------------
|
||||||
|
|
||||||
When composing a ``filter`` or ``exclude`` refinement, it may be necessary to
|
Both ends of a many-to-many relationship get automatic API access to the other
|
||||||
include conditions that span relationships. Relations can be followed as deep
|
end. The API works just as a "backward" one-to-many relationship. See _Backward
|
||||||
as required - just add descriptor names, separated by double underscores, to
|
above.
|
||||||
describe the full path to the query attribute. The query::
|
|
||||||
|
|
||||||
Foo.objects.filter(name1__name2__name3__attribute__lookup=value)
|
The only difference is in the attribute naming: The model that defines the
|
||||||
|
``ManyToManyField`` uses the attribute name of that field itself, whereas the
|
||||||
|
"reverse" model uses the lowercased model name of the original model, plus
|
||||||
|
``'_set'`` (just like reverse one-to-many relationships).
|
||||||
|
|
||||||
... is interpreted as 'get every Foo that has a name1 that has a name2 that
|
An example makes this easier to understand::
|
||||||
has a name3 that has an attribute with lookup matching value'. In the Poll
|
|
||||||
example::
|
|
||||||
|
|
||||||
Choice.objects.filter(poll__slug__startswith="eggs")
|
e = Entry.objects.get(id=3)
|
||||||
|
e.authors.all() # Returns all Author objects for this Entry.
|
||||||
|
e.authors.count()
|
||||||
|
e.authors.filter(name__contains='John')
|
||||||
|
|
||||||
... describes the set of choices for which the related poll has a slug
|
a = Author.objects.get(id=5)
|
||||||
attribute that starts with "eggs". Django automatically composes the joins
|
a.entry_set.all() # Returns all Entry objects for this Author.
|
||||||
and conditions required for the SQL query.
|
|
||||||
|
|
||||||
Creating new related objects
|
Like ``ForeignKey``, ``ManyToManyField`` can specify ``related_name``. In the
|
||||||
============================
|
above example, if the ``ManyToManyField`` in ``Entry`` had specified
|
||||||
|
``related_name='entries'``, then each ``Author`` instance would have an
|
||||||
|
``entries`` attribute instead of ``entry_set``.
|
||||||
|
|
||||||
Related objects are created using the ``create()`` convenience function on
|
One-to-one relationships
|
||||||
the descriptor Manager for relation::
|
------------------------
|
||||||
|
|
||||||
>>> p.choice_set.create(choice="Over easy", votes=0)
|
The semantics of one-to-one relationships will be changing soon, so we don't
|
||||||
>>> p.choice_set.create(choice="Scrambled", votes=0)
|
recommend you use them.
|
||||||
>>> p.choice_set.create(choice="Fertilized", votes=0)
|
|
||||||
>>> p.choice_set.create(choice="Poached", votes=0)
|
|
||||||
>>> p.choice_set.count()
|
|
||||||
4
|
|
||||||
|
|
||||||
Each of those ``create()`` methods is equivalent to (but much simpler than)::
|
How are the backward relationships possible?
|
||||||
|
--------------------------------------------
|
||||||
|
|
||||||
>>> c = Choice(poll_id=p.id, choice="Over easy", votes=0)
|
Other object-relational mappers require you to define relationships on both
|
||||||
>>> c.save()
|
sides. The Django developers believe this is a violation of the DRY (Don't
|
||||||
|
Repeat Yourself) principle, so Django only requires you to define the
|
||||||
|
relationship on one end.
|
||||||
|
|
||||||
Note that when using the `create()`` method, you do not give any value
|
But how is this possible, given that a model class doesn't know which other
|
||||||
for the ``id`` field, nor do you give a value for the field that stores
|
model classes are related to it until those other model classes are loaded?
|
||||||
the relation (``poll_id`` in this case).
|
|
||||||
|
|
||||||
The ``create()`` method always returns the newly created object.
|
The answer lies in the ``INSTALLED_APPS`` setting. The first time any model is
|
||||||
|
loaded, Django iterates over every model in ``INSTALLED_APPS`` and creates the
|
||||||
|
backward relationships in memory as needed. Essentially, one of the functions
|
||||||
|
of ``INSTALLED_APPS`` is to tell Django the entire model domain.
|
||||||
|
|
||||||
Deleting objects
|
Deleting objects
|
||||||
================
|
================
|
||||||
|
@ -1361,23 +1437,23 @@ Deleting objects
|
||||||
The delete method, conveniently, is named ``delete()``. This method immediately
|
The delete method, conveniently, is named ``delete()``. This method immediately
|
||||||
deletes the object and has no return value. Example::
|
deletes the object and has no return value. Example::
|
||||||
|
|
||||||
>>> c.delete()
|
e.delete()
|
||||||
|
|
||||||
Objects can also be deleted in bulk. Every Query Set has a ``delete()`` method
|
You can also delete objects in bulk. Every ``QuerySet`` has a ``delete()``
|
||||||
that will delete all members of the query set. For example::
|
method, which deletes all members of that ``QuerySet``.
|
||||||
|
|
||||||
>>> Polls.objects.filter(pub_date__year=2005).delete()
|
For example, this deletes all ``Entry`` objects with a ``pub_date`` year of
|
||||||
|
2005::
|
||||||
|
|
||||||
would bulk delete all Polls with a year of 2005. Note that ``delete()`` is the
|
Entry.objects.filter(pub_date__year=2005).delete()
|
||||||
only Query Set method that is not exposed on the Manager itself.
|
|
||||||
|
|
||||||
This is a safety mechanism to prevent you from accidentally requesting
|
Note that ``delete()`` is the only ``QuerySet`` method that is not exposed on a
|
||||||
``Polls.objects.delete()``, and deleting *all* the polls.
|
``Manager`` itself. This is a safety mechanism to prevent you from accidentally
|
||||||
|
requesting ``Entry.objects.delete()``, and deleting *all* the entries. If you
|
||||||
|
*do* want to delete all the objects, then you have to explicitly request a
|
||||||
|
complete query set::
|
||||||
|
|
||||||
If you *actually* want to delete all the objects, then you have to explicitly
|
Entry.objects.all().delete()
|
||||||
request a complete query set::
|
|
||||||
|
|
||||||
Polls.objects.all().delete()
|
|
||||||
|
|
||||||
Extra instance methods
|
Extra instance methods
|
||||||
======================
|
======================
|
||||||
|
@ -1397,9 +1473,9 @@ following model::
|
||||||
('M', 'Male'),
|
('M', 'Male'),
|
||||||
('F', 'Female'),
|
('F', 'Female'),
|
||||||
)
|
)
|
||||||
class Person
|
class Person(models.Model):
|
||||||
name = meta.CharField(maxlength=20)
|
name = models.CharField(maxlength=20)
|
||||||
gender = meta.CharField(maxlength=1, choices=GENDER_CHOICES)
|
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
||||||
|
|
||||||
...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
|
...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue