From 8b34a010171d728e3e8c26b04ed46fcb386310c4 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Tue, 5 Jul 2011 20:09:00 +0000 Subject: [PATCH] Improved update() docs in querysets.txt git-svn-id: http://code.djangoproject.com/svn/django/trunk@16516 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- docs/ref/models/querysets.txt | 69 ++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 2bd813d977..68a37ab6fd 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -1278,24 +1278,65 @@ update .. method:: update(**kwargs) Performs an SQL update query for the specified fields, and returns -the number of rows affected. The ``update()`` method is applied instantly and -the only restriction on the :class:`.QuerySet` that is updated is that it can -only update columns in the model's main table. Filtering based on related -fields is still possible. You cannot call ``update()`` on a -:class:`.QuerySet` that has had a slice taken or can otherwise no longer be -filtered. +the number of rows affected. -For example, if you wanted to update all the entries in a particular blog -to use the same headline:: +For example, to turn comments off for all blog entries published in 2010, +you could do this:: - >>> b = Blog.objects.get(pk=1) + >>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False) - # Update all the headlines belonging to this Blog. - >>> Entry.objects.select_related().filter(blog=b).update(headline='Everything is the same') +(This assumes your ``Entry`` model has fields ``pub_date`` and ``comments_on``.) -The ``update()`` method does a bulk update and does not call any ``save()`` -methods on your models, nor does it emit the ``pre_save`` or ``post_save`` -signals (which are a consequence of calling ``save()``). +You can update multiple fields -- there's no limit on how many. For example, +here we update the ``comments_on`` and ``headline`` fields:: + + >>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False, headline='This is old') + +The ``update()`` method is applied instantly, and the only restriction on the +:class:`.QuerySet` that is updated is that it can only update columns in the +model's main table, not on related models. You can't do this, for example:: + + >>> Entry.objects.update(blog__name='foo') # Won't work! + +Filtering based on related fields is still possible, though:: + + >>> Entry.objects.filter(blog__id=1).update(comments_on=True) + +You cannot call ``update()`` on a :class:`.QuerySet` that has had a slice taken +or can otherwise no longer be filtered. + +The ``update()`` method returns the number of affected rows:: + + >>> Entry.objects.filter(id=64).update(comments_on=True) + 1 + + >>> Entry.objects.filter(slug='nonexistent-slug').update(comments_on=True) + 0 + + >>> Entry.objects.filter(pub_date__year=2010).update(comments_on=False) + 132 + +If you're just updating a record and don't need to do anything with the model +object, you should use ``update()`` rather than loading the model object into +memory. The former is more efficient. For example, instead of doing this:: + + e = Entry.objects.get(id=10) + e.comments_on = False + e.save() + +...do this:: + + Entry.objects.get(id=10).update(comments_on=False) + +Finally, note that the ``update()`` method does an update at the SQL level and, +thus, does not call any ``save()`` methods on your models, nor does it emit the +``pre_save`` or ``post_save`` signals (which are a consequence of calling +``save()``). If you want to update a bunch of records for a model that has a +custom ``save()`` method, loop over them and call ``save()``, like this:: + + for e in Entry.objects.filter(pub_date__year=2010): + e.comments_on = False + e.save() delete ~~~~~~