Ticket #3182: update_or_create2.diff

File update_or_create2.diff, 7.0 KB (added by Gary Wilson <gary.wilson@…>, 9 years ago)

added documentation and tests

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

    === modified file 'django/db/models/manager.py'
     
    6868
    6969    def get_or_create(self, **kwargs):
    7070        return self.get_query_set().get_or_create(**kwargs)
    71        
     71
     72    def update_or_create(self, **kwargs):
     73        return self.get_query_set().update_or_create(**kwargs)
     74
    7275    def create(self, **kwargs):
    7376        return self.get_query_set().create(**kwargs)
    7477
  • django/db/models/query.py

    === modified file 'django/db/models/query.py'
     
    240240            obj.save()
    241241            return obj, True
    242242
     243    def update_or_create(self, **kwargs):
     244        """
     245        Looks up an object with the given kwargs, creating one if necessary.
     246        If the object already exists, then its fields are updated with the
     247        values passed in the defaults dictionary.
     248        Returns a tuple of (object, created), where created is a boolean
     249        specifying whether an object was created.
     250        """
     251        obj, created = self.get_or_create(**kwargs)
     252        if not created:
     253            obj.update(**kwargs.pop('defaults', {}))
     254        return obj, created
     255
    243256    def latest(self, field_name=None):
    244257        """
    245258        Returns the latest object, according to the model's 'get_latest_by'
  • docs/db-api.txt

    === modified file 'docs/db-api.txt'
     
    784784
    785785.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
    786786
     787``update_or_create(**kwargs)``
     788~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     789
     790A convenience method for looking up an object with the given kwargs, and then
     791either updating the values of the object if one is found or creating an
     792object if one was not found.
     793
     794This method calls ``get_or_create()`` behind the scenes, and similarly
     795returns a tuple of ``(object, created)``, where``object`` is the updated or
     796created object and ``created`` is a boolean specifying whether a new object
     797was created.
     798
     799This is meant as a shortcut to the following type of code::
     800
     801    obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
     802                       defaults={'birthday': date(1940, 10, 9)})
     803    if not created:
     804            obj.update('birthday'=date(1940, 10, 9))
     805
     806This pattern gets quite unwieldy as the number of fields in a model goes up.
     807The above example can be rewritten using ``update_or_create()`` like so::
     808
     809    obj, created = Person.objects.update_or_create(first_name='John', last_name='Lennon',
     810                       defaults={'birthday': date(1940, 10, 9)})
     811
     812Any keyword arguments passed to ``update_or_create()`` will be used in a
     813call to ``get_or_create()``. If ``get_or_create()`` creates an object, then
     814nothing needs to be done by ``update_or_create()`` and a tuple of the created
     815object and ``True`` is returned. If, on the other hand, ``get_or_create()``
     816does not create a new object, then ``update_or_create()`` will update the
     817object with the values passed in the required ``defaults`` parameter and a
     818tuple of the updated object and ``True`` is returned.
     819
     820The ``defaults`` parameter should be a dict of attribute-value pairs that
     821you want to update. If ``defaults`` is empty or not specified, then
     822``update_or_create()`` will act exactly like ``get_or_create()`` since there
     823would be nothing to update.
     824
     825As with ``get_or_create()``, if you need to use ``update_or_create()`` in a
     826view, please make sure to use it only in ``POST`` requests unless you have a
     827good reason not to. ``GET`` requests shouldn't have any effect on data; use
     828``POST`` whenever a request to a page has a side effect on your data. For
     829more, see `Safe methods`_ in the HTTP spec.
     830
     831.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
     832
    787833``count()``
    788834~~~~~~~~~~~
    789835
Back to Top