summaryrefslogtreecommitdiff
path: root/docs/ref/models
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2013-08-09 14:17:30 +0100
committerAndrew Godwin <andrew@aeracode.org>2013-08-09 14:17:30 +0100
commitde64c4d6e97c980fb4c0ace045fc4070b3f763d9 (patch)
tree045c8af6a88fa964cf7e284970a6e93d53941a79 /docs/ref/models
parentfddc5957c53bd654312c4a238a8cdcfe5f4ef4cc (diff)
parentb575d690bbc1c4cd7f575346132c09fca8c736a7 (diff)
Merge remote-tracking branch 'core/master' into schema-alteration
Conflicts: django/core/management/commands/flush.py django/core/management/commands/syncdb.py django/db/models/loading.py docs/internals/deprecation.txt docs/ref/django-admin.txt docs/releases/1.7.txt
Diffstat (limited to 'docs/ref/models')
-rw-r--r--docs/ref/models/fields.txt22
-rw-r--r--docs/ref/models/instances.txt24
-rw-r--r--docs/ref/models/options.txt7
-rw-r--r--docs/ref/models/querysets.txt145
4 files changed, 137 insertions, 61 deletions
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 869996643f..01215884c4 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -152,11 +152,20 @@ method to retrieve the human-readable name for the field's current value. See
:meth:`~django.db.models.Model.get_FOO_display` in the database API
documentation.
-Finally, note that choices can be any iterable object -- not necessarily a list
-or tuple. This lets you construct choices dynamically. But if you find yourself
-hacking :attr:`~Field.choices` to be dynamic, you're probably better off using a
-proper database table with a :class:`ForeignKey`. :attr:`~Field.choices` is
-meant for static data that doesn't change much, if ever.
+Note that choices can be any iterable object -- not necessarily a list or tuple.
+This lets you construct choices dynamically. But if you find yourself hacking
+:attr:`~Field.choices` to be dynamic, you're probably better off using a proper
+database table with a :class:`ForeignKey`. :attr:`~Field.choices` is meant for
+static data that doesn't change much, if ever.
+
+.. versionadded:: 1.7
+
+Unless :attr:`blank=False<Field.blank>` is set on the field along with a
+:attr:`~Field.default` then a label containing ``"---------"`` will be rendered
+with the select box. To override this behavior, add a tuple to ``choices``
+containing ``None``; e.g. ``(None, 'Your String For Display')``.
+Alternatively, you can use an empty string instead of ``None`` where this makes
+sense - such as on a :class:`~django.db.models.CharField`.
``db_column``
-------------
@@ -874,6 +883,9 @@ are converted to lowercase.
``192.0.2.1``. Default is disabled. Can only be used
when ``protocol`` is set to ``'both'``.
+If you allow for blank values, you have to allow for null values since blank
+values are stored as null.
+
``NullBooleanField``
--------------------
diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt
index f06866d9a1..cb8570afdc 100644
--- a/docs/ref/models/instances.txt
+++ b/docs/ref/models/instances.txt
@@ -118,7 +118,7 @@ validation for your own manually created models. For example::
article.full_clean()
except ValidationError as e:
# Do something based on the errors contained in e.message_dict.
- # Display them to a user, or handle them programatically.
+ # Display them to a user, or handle them programmatically.
pass
The first step ``full_clean()`` performs is to clean each individual field.
@@ -140,15 +140,19 @@ attributes on your model if desired. For instance, you could use it to
automatically provide a value for a field, or to do validation that requires
access to more than a single field::
- def clean(self):
- import datetime
- from django.core.exceptions import ValidationError
- # Don't allow draft entries to have a pub_date.
- if self.status == 'draft' and self.pub_date is not None:
- raise ValidationError('Draft entries may not have a publication date.')
- # Set the pub_date for published items if it hasn't been set already.
- if self.status == 'published' and self.pub_date is None:
- self.pub_date = datetime.date.today()
+ import datetime
+ from django.core.exceptions import ValidationError
+ from django.db import models
+
+ class Article(models.Model):
+ ...
+ def clean(self):
+ # Don't allow draft entries to have a pub_date.
+ if self.status == 'draft' and self.pub_date is not None:
+ raise ValidationError('Draft entries may not have a publication date.')
+ # Set the pub_date for published items if it hasn't been set already.
+ if self.status == 'published' and self.pub_date is None:
+ self.pub_date = datetime.date.today()
Any :exc:`~django.core.exceptions.ValidationError` exceptions raised by
``Model.clean()`` will be stored in a special key error dictionary key,
diff --git a/docs/ref/models/options.txt b/docs/ref/models/options.txt
index 6eeed51b6f..6415a9d2da 100644
--- a/docs/ref/models/options.txt
+++ b/docs/ref/models/options.txt
@@ -90,7 +90,7 @@ Django quotes column and table names behind the scenes.
The name of an orderable field in the model, typically a :class:`DateField`,
:class:`DateTimeField`, or :class:`IntegerField`. This specifies the default
- field to use in your model :class:`Manager`'s
+ field to use in your model :class:`Manager`’s
:meth:`~django.db.models.query.QuerySet.latest` and
:meth:`~django.db.models.query.QuerySet.earliest` methods.
@@ -227,9 +227,8 @@ Django quotes column and table names behind the scenes.
.. attribute:: Options.permissions
Extra permissions to enter into the permissions table when creating this object.
- Add, delete and change permissions are automatically created for each object
- that has ``admin`` set. This example specifies an extra permission,
- ``can_deliver_pizzas``::
+ Add, delete and change permissions are automatically created for each
+ model. This example specifies an extra permission, ``can_deliver_pizzas``::
permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 3963785733..0f08022179 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -110,7 +110,7 @@ described here.
.. admonition:: You can't share pickles between versions
- Pickles of QuerySets are only valid for the version of Django that
+ Pickles of ``QuerySets`` are only valid for the version of Django that
was used to generate them. If you generate a pickle using Django
version N, there is no guarantee that pickle will be readable with
Django version N+1. Pickles should not be used as part of a long-term
@@ -121,9 +121,7 @@ described here.
QuerySet API
============
-Though you usually won't create one manually — you'll go through a
-:class:`~django.db.models.Manager` — here's the formal declaration of a
-``QuerySet``:
+Here's the formal declaration of a ``QuerySet``:
.. class:: QuerySet([model=None, query=None, using=None])
@@ -300,14 +298,30 @@ Be cautious when ordering by fields in related models if you are also using
:meth:`distinct()`. See the note in :meth:`distinct` for an explanation of how
related model ordering can change the expected results.
-It is permissible to specify a multi-valued field to order the results by (for
-example, a :class:`~django.db.models.ManyToManyField` field). Normally
-this won't be a sensible thing to do and it's really an advanced usage
-feature. However, if you know that your queryset's filtering or available data
-implies that there will only be one ordering piece of data for each of the main
-items you are selecting, the ordering may well be exactly what you want to do.
-Use ordering on multi-valued fields with care and make sure the results are
-what you expect.
+.. note::
+ It is permissible to specify a multi-valued field to order the results by
+ (for example, a :class:`~django.db.models.ManyToManyField` field, or the
+ reverse relation of a :class:`~django.db.models.ForeignKey` field).
+
+ Consider this case::
+
+ class Event(Model):
+ parent = models.ForeignKey('self', related_name='children')
+ date = models.DateField()
+
+ Event.objects.order_by('children__date')
+
+ Here, there could potentially be multiple ordering data for each ``Event``;
+ each ``Event`` with multiple ``children`` will be returned multiple times
+ into the new ``QuerySet`` that ``order_by()`` creates. In other words,
+ using ``order_by()`` on the ``QuerySet`` could return more items than you
+ were working on to begin with - which is probably neither expected nor
+ useful.
+
+ Thus, take care when using multi-valued field to order the results. **If**
+ you can be sure that there will only be one ordering piece of data for each
+ of the items you're ordering, this approach should not present problems. If
+ not, make sure the results are what you expect.
There's no way to specify whether ordering should be case sensitive. With
respect to case-sensitivity, Django will order results however your database
@@ -388,7 +402,7 @@ field names, the database will only compare the specified field names.
.. note::
When you specify field names, you *must* provide an ``order_by()`` in the
- QuerySet, and the fields in ``order_by()`` must start with the fields in
+ ``QuerySet``, and the fields in ``order_by()`` must start with the fields in
``distinct()``, in the same order.
For example, ``SELECT DISTINCT ON (a)`` gives you the first row for each
@@ -789,8 +803,8 @@ stop the deluge of database queries that is caused by accessing related objects,
but the strategy is quite different.
``select_related`` works by creating a SQL join and including the fields of the
-related object in the SELECT statement. For this reason, ``select_related`` gets
-the related objects in the same database query. However, to avoid the much
+related object in the ``SELECT`` statement. For this reason, ``select_related``
+gets the related objects in the same database query. However, to avoid the much
larger result set that would result from joining across a 'many' relationship,
``select_related`` is limited to single-valued relationships - foreign key and
one-to-one.
@@ -819,39 +833,54 @@ For example, suppose you have these models::
return u"%s (%s)" % (self.name, u", ".join([topping.name
for topping in self.toppings.all()]))
-and run this code::
+and run::
>>> Pizza.objects.all()
[u"Hawaiian (ham, pineapple)", u"Seafood (prawns, smoked salmon)"...
-The problem with this code is that it will run a query on the Toppings table for
-**every** item in the Pizza ``QuerySet``. Using ``prefetch_related``, this can
-be reduced to two:
+The problem with this is that every time ``Pizza.__unicode__()`` asks for
+``self.toppings.all()`` it has to query the database, so
+``Pizza.objects.all()`` will run a query on the Toppings table for **every**
+item in the Pizza ``QuerySet``.
+
+We can reduce to just two queries using ``prefetch_related``:
>>> Pizza.objects.all().prefetch_related('toppings')
-All the relevant toppings will be fetched in a single query, and used to make
-``QuerySets`` that have a pre-filled cache of the relevant results. These
-``QuerySets`` are then used in the ``self.toppings.all()`` calls.
+This implies a ``self.toppings.all()`` for each ``Pizza``; now each time
+``self.toppings.all()`` is called, instead of having to go to the database for
+the items, it will find them in a prefetched ``QuerySet`` cache that was
+populated in a single query.
-The additional queries are executed after the QuerySet has begun to be evaluated
-and the primary query has been executed. Note that the result cache of the
-primary QuerySet and all specified related objects will then be fully loaded
-into memory, which is often avoided in other cases - even after a query has been
-executed in the database, QuerySet normally tries to make uses of chunking
-between the database to avoid loading all objects into memory before you need
-them.
+That is, all the relevant toppings will have been fetched in a single query,
+and used to make ``QuerySets`` that have a pre-filled cache of the relevant
+results; these ``QuerySets`` are then used in the ``self.toppings.all()`` calls.
-Also remember that, as always with QuerySets, any subsequent chained methods
-which imply a different database query will ignore previously cached results,
-and retrieve data using a fresh database query. So, if you write the following:
+The additional queries in ``prefetch_related()`` are executed after the
+``QuerySet`` has begun to be evaluated and the primary query has been executed.
- >>> pizzas = Pizza.objects.prefetch_related('toppings')
- >>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]
+Note that the result cache of the primary ``QuerySet`` and all specified related
+objects will then be fully loaded into memory. This changes the typical
+behavior of ``QuerySets``, which normally try to avoid loading all objects into
+memory before they are needed, even after a query has been executed in the
+database.
-...then the fact that ``pizza.toppings.all()`` has been prefetched will not help
-you - in fact it hurts performance, since you have done a database query that
-you haven't used. So use this feature with caution!
+.. note::
+
+ Remember that, as always with ``QuerySets``, any subsequent chained methods
+ which imply a different database query will ignore previously cached
+ results, and retrieve data using a fresh database query. So, if you write
+ the following:
+
+ >>> pizzas = Pizza.objects.prefetch_related('toppings')
+ >>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]
+
+ ...then the fact that ``pizza.toppings.all()`` has been prefetched will not
+ help you. The ``prefetch_related('toppings')`` implied
+ ``pizza.toppings.all()``, but ``pizza.toppings.filter()`` is a new and
+ different query. The prefetched cache can't help here; in fact it hurts
+ performance, since you have done a database query that you haven't used. So
+ use this feature with caution!
You can also use the normal join syntax to do related fields of related
fields. Suppose we have an additional model to the example above::
@@ -904,7 +933,7 @@ additional queries on the ``ContentType`` table if the relevant rows have not
already been fetched.
``prefetch_related`` in most cases will be implemented using a SQL query that
-uses the 'IN' operator. This means that for a large QuerySet a large 'IN' clause
+uses the 'IN' operator. This means that for a large ``QuerySet`` a large 'IN' clause
could be generated, which, depending on the database, might have performance
problems of its own when it comes to parsing or executing the SQL query. Always
profile for your use case!
@@ -979,14 +1008,13 @@ of the arguments is required, but you should use at least one of them.
``select_params`` parameter. Since ``select_params`` is a sequence and
the ``select`` attribute is a dictionary, some care is required so that
the parameters are matched up correctly with the extra select pieces.
- In this situation, you should use a
- :class:`django.utils.datastructures.SortedDict` for the ``select``
- value, not just a normal Python dictionary.
+ In this situation, you should use a :class:`collections.OrderedDict` for
+ the ``select`` value, not just a normal Python dictionary.
This will work, for example::
Blog.objects.extra(
- select=SortedDict([('a', '%s'), ('b', '%s')]),
+ select=OrderedDict([('a', '%s'), ('b', '%s')]),
select_params=('one', 'two'))
The only thing to be careful about when using select parameters in
@@ -1264,6 +1292,28 @@ unexpectedly blocking.
Using ``select_for_update`` on backends which do not support
``SELECT ... FOR UPDATE`` (such as SQLite) will have no effect.
+raw
+~~~
+
+.. method:: raw(raw_query, params=None, translations=None)
+
+.. versionchanged:: 1.7
+
+ ``raw`` was moved to the ``QuerySet`` class. It was previously only on
+ :class:`~django.db.models.Manager`.
+
+Takes a raw SQL query, executes it, and returns a
+``django.db.models.query.RawQuerySet`` instance. This ``RawQuerySet`` instance
+can be iterated over just like an normal ``QuerySet`` to provide object instances.
+
+See the :ref:`executing-raw-queries` for more information.
+
+.. warning::
+
+ ``raw()`` always triggers a new query and doesn't account for previous
+ filtering. As such, it should generally be called from the ``Manager`` or
+ from a fresh ``QuerySet`` instance.
+
Methods that do not return QuerySets
------------------------------------
@@ -1866,6 +1916,17 @@ DO_NOTHING do not prevent taking the fast-path in deletion.
Note that the queries generated in object deletion is an implementation
detail subject to change.
+as_manager
+~~~~~~~~~~
+
+.. classmethod:: as_manager()
+
+.. versionadded:: 1.7
+
+Class method that returns an instance of :class:`~django.db.models.Manager`
+with a copy of the ``QuerySet``’s methods. See
+:ref:`create-manager-with-queryset-methods` for more details.
+
.. _field-lookups:
Field lookups