Author: mtredinnick
Date: 2011-08-25 23:19:30 -0700 (Thu, 25 Aug 2011)
New Revision: 16692

Modified:
   django/trunk/docs/ref/models/options.txt
   django/trunk/docs/ref/models/querysets.txt
Log:
Be very clear about when it's appropriate to use defer() and only().

I've been seeing a bit of over-reliance on defer() and only() in code
around the place and it's generally better modelled with normalised data
or shadow (unmanaged) models. This commit makes this position clearer.

Modified: django/trunk/docs/ref/models/options.txt
===================================================================
--- django/trunk/docs/ref/models/options.txt    2011-08-26 05:28:58 UTC (rev 
16691)
+++ django/trunk/docs/ref/models/options.txt    2011-08-26 06:19:30 UTC (rev 
16692)
@@ -91,7 +91,8 @@
 
     Defaults to ``True``, meaning Django will create the appropriate database
     tables in :djadmin:`syncdb` and remove them as part of a :djadmin:`reset`
-    management command. That is, Django *manages* the database tables' 
lifecycles.
+    management command. That is, Django *manages* the database tables'
+    lifecycles.
 
     If ``False``, no database table creation or deletion operations will be
     performed for this model. This is useful if the model represents an 
existing
@@ -99,21 +100,21 @@
     the *only* difference when ``managed=False``. All other aspects of
     model handling are exactly the same as normal. This includes
 
-        1. Adding an automatic primary key field to the model if you don't 
declare
-           it.  To avoid confusion for later code readers, it's recommended to
-           specify all the columns from the database table you are modeling 
when
-           using unmanaged models.
+       1. Adding an automatic primary key field to the model if you don't
+          declare it.  To avoid confusion for later code readers, it's
+          recommended to specify all the columns from the database table you
+          are modeling when using unmanaged models.
 
-        2. If a model with ``managed=False`` contains a
-           :class:`~django.db.models.ManyToManyField` that points to another
-           unmanaged model, then the intermediate table for the many-to-many 
join
-           will also not be created. However, the intermediary table between 
one
-           managed and one unmanaged model *will* be created.
+       2. If a model with ``managed=False`` contains a
+          :class:`~django.db.models.ManyToManyField` that points to another
+          unmanaged model, then the intermediate table for the many-to-many
+          join will also not be created. However, the intermediary table
+          between one managed and one unmanaged model *will* be created.
 
-           If you need to change this default behavior, create the intermediary
-           table as an explicit model (with ``managed`` set as needed) and use 
the
-           :attr:`ManyToManyField.through` attribute to make the relation use 
your
-           custom model.
+          If you need to change this default behavior, create the intermediary
+          table as an explicit model (with ``managed`` set as needed) and use
+          the :attr:`ManyToManyField.through` attribute to make the relation
+          use your custom model.
 
     For tests involving models with ``managed=False``, it's up to you to ensure
     the correct tables are created as part of the test setup.

Modified: django/trunk/docs/ref/models/querysets.txt
===================================================================
--- django/trunk/docs/ref/models/querysets.txt  2011-08-26 05:28:58 UTC (rev 
16691)
+++ django/trunk/docs/ref/models/querysets.txt  2011-08-26 06:19:30 UTC (rev 
16692)
@@ -139,7 +139,7 @@
         clause or a default ordering on the model. ``False`` otherwise.
 
     .. attribute:: db
-    
+
         The database that will be used if this query is executed now.
 
     .. note::
@@ -906,10 +906,22 @@
     analyzed your queries closely and understand *exactly* what information
     you need and have measured that the difference between returning the
     fields you need and the full set of fields for the model will be
-    significant. When you are initially developing your applications, don't
-    bother using ``defer()``; leave it until your query construction has
-    settled down and you understand where the hot-points are.
+    significant.
 
+    Even if you think you are in the advanced use-case situation, **only use
+    defer() when you cannot, at queryset load time, determine if you will need
+    the extra fields or not**. If you are frequently loading and using a
+    particular subset of your data, the best choice you can make is to
+    normalize your models and put the non-loaded data into a separate model
+    (and database table). If the columns *must* stay in the one table for some
+    reason, create a model with ``Meta.managed = False`` (see the
+    :py:attr:`managed attribute <django.db.models.Options.managed>`
+    documentation) containing just the fields you normally need to load and use
+    that where you might otherwise call ``defer()``. This makes your code more
+    explicit to the reader, is slightly faster and consumes a little less
+    memory in the Python process.
+
+
 only
 ~~~~
 
@@ -946,6 +958,10 @@
     # existing set of fields).
     Entry.objects.defer("body").only("headline", "body")
 
+All of the cautions in the note for the :py:meth:`defer` documentation apply to
+``only()`` as well. Use it cautiously and only after exhausting your other
+options.
+
 using
 ~~~~~
 

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to