Ticket #3182: 3182.diff

File 3182.diff, 12.3 KB (added by Gary Wilson, 15 years ago)

took save() out of the assignment loop in update() and made a few tweaks to the docs.

  • django/db/models/base.py

    === modified file 'django/db/models/base.py'
     
    331331
    332332    save.alters_data = True
    333333
     334    def update(self, **kwargs):
     335        """
     336        Set the object's fields to the new values passed in as keyword
     337        arguments and then save the object.  Fields not specified in the
     338        keyword arguments will not be altered.
     339        """
     340        for k, v in kwargs.iteritems():
     341            setattr(self, k, v)
     342        self.save()
     343
     344    update.alters_data = True
     345
    334346    def save_base(self, raw=False, cls=None, force_insert=False,
    335347            force_update=False):
    336348        """
  • django/db/models/manager.py

    === modified file 'django/db/models/manager.py'
     
    119119    def get_or_create(self, **kwargs):
    120120        return self.get_query_set().get_or_create(**kwargs)
    121121
     122    def update_or_create(self, **kwargs):
     123        return self.get_query_set().update_or_create(**kwargs)
     124
    122125    def create(self, **kwargs):
    123126        return self.get_query_set().create(**kwargs)
    124127
  • django/db/models/query.py

    === modified file 'django/db/models/query.py'
     
    379379                except self.model.DoesNotExist:
    380380                    raise e
    381381
     382    def update_or_create(self, **kwargs):
     383        """
     384        Looks up an object with the given kwargs, creating one if necessary.
     385        If the object already exists, then its fields are updated with the
     386        values passed in the defaults dictionary.
     387        Returns a tuple of (object, created), where created is a boolean
     388        specifying whether an object was created.
     389        """
     390        obj, created = self.get_or_create(**kwargs)
     391        if not created:
     392            obj.update(**kwargs.pop('defaults', {}))
     393        return obj, created
     394
    382395    def latest(self, field_name=None):
    383396        """
    384397        Returns the latest object, according to the model's 'get_latest_by'
  • docs/ref/models/instances.txt

    === modified file 'docs/ref/models/instances.txt'
     
    55========================
    66
    77.. currentmodule:: django.db.models
    8    
     8
    99This document describes the details of the ``Model`` API. It builds on the
    1010material presented in the :ref:`model <topics-db-models>` and :ref:`database
    1111query <topics-db-queries>` guides, so you'll probably want to read and
     
    4949your object the first time you call ``save()``::
    5050
    5151    >>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
    52     >>> b2.id     # Returns None, because b doesn't have an ID yet.
     52    >>> b2.id     # Returns None, because b2 doesn't have an ID yet.
    5353    >>> b2.save()
    5454    >>> b2.id     # Returns the ID of your new object.
    5555
     
    9494Given the above ``'Cheddar Talk'`` blog example, this example would override the
    9595previous record in the database::
    9696
    97     b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
    98     b4.save()  # Overrides the previous blog with ID=3!
     97    >>> b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
     98    >>> b4.save()  # Overrides the previous blog with ID=3!
    9999
    100100See `How Django knows to UPDATE vs. INSERT`_, below, for the reason this
    101101happens.
     
    187187errors that are difficult to track down. This feature is for advanced use
    188188only.
    189189
     190
     191.. _ref-models-update:
     192
     193Updating objects
     194================
     195
     196.. versionadded:: 1.1
     197
     198To update and save a model instance in one step, call ``update()``:
     199
     200.. method:: Model.update(**kwargs)
     201
     202A convenience method for updating and saving a model instance in one step,
     203where the keyword arguments are the names of the fields on your model you want
     204to update.  Like ``save()``, the ``update()`` method has no return value.
     205
     206Given the earlier ``'Not Cheddar'`` blog example, this example would update
     207and save the existing model instance::
     208
     209    >>> b4.name
     210    'Not Cheddar'
     211    >>> b4.update(name='All Cheddar', tagline='Nothing but cheddar cheese')
     212    >>> b4.name
     213    'All Cheddar'
     214
     215Since ``update()`` calls ``save()`` behind the scenes, Django will hit the
     216database every time ``update()`` is called.
     217
     218
    190219.. _model-instance-methods:
    191220
    192221Other model instance methods
  • docs/ref/models/querysets.txt

    === modified file 'docs/ref/models/querysets.txt'
     
    896896
    897897.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
    898898
     899``update_or_create(**kwargs)``
     900~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     901
     902A convenience method for looking up an object with the given kwargs, and then
     903either updating the values of the object if one is found or creating an
     904object if one was not found.
     905
     906This method calls ``get_or_create()`` behind the scenes, and similarly
     907returns a tuple of ``(object, created)``, where ``object`` is the updated or
     908created object and ``created`` is a boolean specifying whether a new object
     909was created.
     910
     911This is meant as a shortcut to the following type of code::
     912
     913    obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
     914                       defaults={'birthday': date(1940, 10, 9)})
     915    if not created:
     916        obj.update(birthday=date(1940, 10, 9))
     917
     918This pattern gets quite unwieldy as the number of fields in a model goes up.
     919The above example can be rewritten using ``update_or_create()`` like so::
     920
     921    obj, created = Person.objects.update_or_create(first_name='John', last_name='Lennon',
     922                       defaults={'birthday': date(1940, 10, 9)})
     923
     924Any keyword arguments passed to ``update_or_create()`` will be used in a
     925call to ``get_or_create()``. If ``get_or_create()`` creates an object, then
     926nothing needs to be done by ``update_or_create()`` and a tuple of the created
     927object and ``True`` is returned. If, on the other hand, ``get_or_create()``
     928does not create a new object, then ``update_or_create()`` will update the
     929object with the values passed in the ``defaults`` parameter and a tuple of
     930the updated object and ``True`` is returned.
     931
     932The ``defaults`` parameter should be a dict of attribute-value pairs that
     933you want to update. If ``defaults`` is empty or not specified, then
     934``update_or_create()`` will act exactly like ``get_or_create()`` since there
     935would be nothing to update.
     936
     937As with ``get_or_create()``, if you need to use ``update_or_create()`` in a
     938view, please make sure to use it only in ``POST`` requests unless you have a
     939good reason not to. ``GET`` requests shouldn't have any effect on data; use
     940``POST`` whenever a request to a page has a side effect on your data. For
     941more, see `Safe methods`_ in the HTTP spec.
     942
     943.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
     944
    899945``count()``
    900946~~~~~~~~~~~
    901947
  • tests/modeltests/update/models.py

    === modified file 'tests/modeltests/update/models.py'
     
    11"""
    2 Tests for the update() queryset method that allows in-place, multi-object
    3 updates.
     2Tests for the update() queryset and model methods that allow in-place updates
     3to multiple objects or a single object.
    44"""
    55
    66from django.db import models
     
    2222
    2323
    2424__test__ = {'API_TESTS': """
     25# QuerySet method #############################################################
     26
    2527>>> DataPoint(name="d0", value="apple").save()
    2628>>> DataPoint(name="d2", value="banana").save()
    2729>>> d3 = DataPoint.objects.create(name="d3", value="banana")
    2830>>> RelatedPoint(name="r1", data=d3).save()
    2931
    3032Objects are updated by first filtering the candidates into a queryset and then
    31 calling the update() method. It executes immediately and returns nothing.
     33calling the update() method. It executes immediately and returns the number of
     34objects affected.
    3235
    3336>>> DataPoint.objects.filter(value="apple").update(name="d1")
    34371
     
    7477    ...
    7578AssertionError: Cannot update a query once a slice has been taken.
    7679
     80# Model method ################################################################
     81
     82# Get an existing DataPoint object.
     83>>> d = DataPoint.objects.get(name="d2")
     84>>> d.value, d.another_value
     85(u'thing', u'peaches')
     86
     87# Update multiple fields.
     88>>> d.update(value='oranges', another_value='apples')
     89
     90# Check that the object was updated.
     91>>> d.value, d.another_value
     92('oranges', 'apples')
     93
     94# Check that the object was saved.
     95>>> d = DataPoint.objects.get(name="d2", value="oranges", another_value="apples")
     96>>> d.value, d.another_value
     97(u'oranges', u'apples')
     98
     99# Get an existing RelatedPoint object.
     100>>> r = RelatedPoint.objects.get(name="r1")
     101>>> r.data
     102<DataPoint: d1>
     103
     104# Update the ForeignKey field.
     105>>> r.update(data=d)
     106>>> r.data
     107<DataPoint: d2>
     108
     109# Check that the object was saved.
     110>>> RelatedPoint.objects.get(name="r1").data
     111<DataPoint: d2>
     112
     113# You can also update an object that has not yet been saved.
     114>>> d = DataPoint(name="d4", value="planes", another_value="trains")
     115>>> d.update(another_value="automobiles")
     116>>> d.value, d.another_value
     117('planes', 'automobiles')
    77118"""
    78119}
  • tests/modeltests/update_or_create/models.py

    === added directory 'tests/modeltests/update_or_create'
    === added file 'tests/modeltests/update_or_create/__init__.py'
    === added file 'tests/modeltests/update_or_create/models.py'
     
     1"""
     2update_or_create() tries to look up an object with the given parameters.
     3If an object is found, it updates the object.  If an object isn't found, it
     4creates one with the given parameters.
     5"""
     6
     7from django.db import models
     8
     9class Person(models.Model):
     10    first_name = models.CharField(max_length=100)
     11    last_name = models.CharField(max_length=100)
     12    birthday = models.DateField()
     13
     14    def __str__(self):
     15        return '%s %s, Birthday: %s' % (self.first_name, self.last_name,
     16                                        self.birthday)
     17
     18    class Meta:
     19        ordering = ('last_name',)
     20
     21__test__ = {'API_TESTS': """
     22# Create a Person.
     23>>> from datetime import date
     24>>> p = Person.objects.create(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
     25
     26# Only one Person is in the database at this point.
     27>>> Person.objects.all()
     28[<Person: John Lennon, Birthday: 1940-10-09>]
     29
     30# update_or_create() a Person with the same name.
     31>>> p, created = Person.objects.update_or_create(first_name='John', last_name='Lennon', defaults={'birthday': date(1970, 10, 9)})
     32
     33# update_or_create() didn't have to create an object.
     34>>> created
     35False
     36
     37# There's still only one Person in the database, and their birthday was updated.
     38>>> Person.objects.all()
     39[<Person: John Lennon, Birthday: 1970-10-09>]
     40
     41# update_or_create() a Person with a different name.
     42>>> p, created = Person.objects.update_or_create(first_name='George', last_name='Harrison', defaults={'birthday': date(1943, 2, 25)})
     43>>> created
     44True
     45
     46# Two People in the database now.
     47>>> Person.objects.all()
     48[<Person: George Harrison, Birthday: 1943-02-25>, <Person: John Lennon, Birthday: 1970-10-09>]
     49
     50# If we execute the exact same statement, it won't create a Person.
     51>>> p, created = Person.objects.update_or_create(first_name='George', last_name='Harrison', defaults={'birthday': date(1943, 2, 25)})
     52>>> created
     53False
     54
     55# The two People in the database haven't changed.
     56>>> Person.objects.all()
     57[<Person: George Harrison, Birthday: 1943-02-25>, <Person: John Lennon, Birthday: 1970-10-09>]
     58
     59# update_or_create() can take an empty 'defaults' parameter, but in this
     60# situation behaves exactly like get_or_create().  This is useful if you are
     61# building the 'defaults' dictionary dynamically.
     62>>> p, created = Person.objects.update_or_create(first_name='George', last_name='Harrison', defaults={})
     63>>> created
     64False
     65
     66# A different name with an empty 'defaults'.
     67>>> p, created = Person.objects.update_or_create(first_name='John', last_name='Smith', birthday=date(1950, 2, 10), defaults={})
     68>>> created
     69True
     70
     71>>> Person.objects.all()
     72[<Person: George Harrison, Birthday: 1943-02-25>, <Person: John Lennon, Birthday: 1970-10-09>, <Person: John Smith, Birthday: 1950-02-10>]
     73"""}
Back to Top