Django

Code

Ticket #3182: update_and_update_or_create.diff

File update_and_update_or_create.diff, 11.5 kB (added by Gary Wilson <gary.wilson@gmail.com>, 2 years ago)

update() from #3180 and update_or_create() together

  • tests/modeltests/update/models.py

    old new  
     1""" 
     234. update() 
     3 
     4update() will update an object's fields with the paramaters passed to it, 
     5and then save the object. 
     6""" 
     7 
     8from django.db import models 
     9from django.core import validators 
     10 
     11class User(models.Model): 
     12    username = models.CharField(maxlength=30, unique=True, 
     13                                validator_list=[validators.isAlphaNumeric]) 
     14    first_name = models.CharField(maxlength=100) 
     15    last_name = models.CharField(maxlength=100) 
     16 
     17    def __str__(self): 
     18        return '%s %s "%s"' % (self.first_name, self.last_name, self.username) 
     19 
     20    class Meta: 
     21        ordering = ('username',) 
     22 
     23__test__ = {'API_TESTS':""" 
     24# Lets create a User. 
     25>>> u1 = User.objects.create(username='brave', first_name='Sir', last_name='Robin') 
     26 
     27# Only one User in the database so far. 
     28>>> User.objects.all() 
     29[<User: Sir Robin "brave">] 
     30 
     31# Now we update the user's username and check that it was indeed updated. 
     32>>> u1.update(username='notsobrave') 
     33>>> u1.username 
     34'notsobrave' 
     35 
     36# We should still only have one User in the database. 
     37>>> User.objects.all() 
     38[<User: Sir Robin "notsobrave">] 
     39 
     40# We should be able to grab the User by its new username. 
     41>>> u1 = User.objects.get(username='notsobrave') 
     42 
     43# And we should no longer have a User with username 'brave'. 
     44>>> User.objects.filter(username='brave').count() 
     450L 
     46 
     47# Let's create another User. 
     48>>> u2 = User.objects.create(username='brave', first_name='Sir', last_name='Lancelot') 
     49 
     50# Two Users in the database now, and we also have the first User's updated data. 
     51>>> User.objects.all() 
     52[<User: Sir Lancelot "brave">, <User: Sir Robin "notsobrave">] 
     53 
     54# We can update more than one field at a time. 
     55>>> u1.update(username='pure', last_name='Galahad') 
     56 
     57# The user did indeed get updated. 
     58>>> User.objects.all() 
     59[<User: Sir Lancelot "brave">, <User: Sir Galahad "pure">] 
     60 
     61# If we have a dictionary of fields to change, we can pass that to 
     62# update() also. 
     63>>> data = {'username': 'knight', 'first_name': 'Knight'} 
     64>>> u1.update(**data) 
     65>>> u1 
     66<User: Knight Galahad "knight"> 
     67>>> User.objects.all() 
     68[<User: Sir Lancelot "brave">, <User: Knight Galahad "knight">] 
     69"""} 
  • tests/modeltests/update_or_create/models.py

    old new  
     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/base.py

    old new  
    217217 
    218218    save.alters_data = True 
    219219 
     220    def update(self, **kwargs): 
     221        """ 
     222        Set the object's fields to the new values passed in as keyword 
     223        arguments and then save the object.  Fields not specified in the 
     224        keyword arguments will not be altered. 
     225        """ 
     226        # Nothing to do if we have no keyword arguments. 
     227        if kwargs: 
     228            self.__dict__.update(kwargs) 
     229            self.save() 
     230 
     231    update.alters_data = True 
     232 
    220233    def validate(self): 
    221234        """ 
    222235        First coerces all fields on this instance to their proper Python types. 
  • django/db/models/manager.py

    old new  
    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

    old new  
    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

    old new  
    121121Saving changes to objects 
    122122========================= 
    123123 
    124 To save changes to an object that's already in the database, use ``save()``. 
    125  
    126 Given a ``Blog`` instance ``b5`` that has already been saved to the database, 
    127 this example changes its name and updates its record in the database:: 
    128  
    129     b5.name = 'New name' 
    130     b5.save() 
    131  
    132 This performs an ``UPDATE`` SQL statement behind the scenes. Django doesn't hit 
     124``save()`` 
     125---------- 
     126 
     127Use the ``save()`` method to save an object to the database after making 
     128changes to it:: 
     129 
     130    newblog.name = "Brave New World" 
     131    newblog.save() 
     132 
     133This performs an ``UPDATE`` SQL statement behind the scenes (see the 
     134`How Django knows to UPDATE vs. INSERT`_ section below).  Django doesn't hit 
    133135the database until you explicitly call ``save()``. 
    134136 
    135137The ``save()`` method has no return value. 
    136138 
     139``update(**kwargs)`` 
     140-------------------- 
     141 
     142A convenience method for updating and saving an object all in one step, where 
     143(``**kwargs``) are the attributes to update.  Like ``save()``, the 
     144``update()`` method has no return value. 
     145 
     146Using ``update()``, the above code example could be rewritten as:: 
     147 
     148    newblog.update(name="Brave New World") 
     149 
     150Since ``update()`` calls ``save()`` behind the scenes, Django will hit the 
     151database every time ``update()`` is called. 
     152 
    137153How Django knows to UPDATE vs. INSERT 
    138154------------------------------------- 
    139155 
     
    784800 
    785801.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1 
    786802 
     803``update_or_create(**kwargs)`` 
     804~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     805 
     806A convenience method for looking up an object with the given kwargs, and then 
     807either updating the values of the object if one is found or creating an 
     808object if one was not found. 
     809 
     810This method calls ``get_or_create()`` behind the scenes, and similarly 
     811returns a tuple of ``(object, created)``, where``object`` is the updated or 
     812created object and ``created`` is a boolean specifying whether a new object 
     813was created. 
     814 
     815This is meant as a shortcut to the following type of code:: 
     816 
     817    obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon', 
     818                       defaults={'birthday': date(1940, 10, 9)}) 
     819    if not created: 
     820            obj.update('birthday'=date(1940, 10, 9)) 
     821 
     822This pattern gets quite unwieldy as the number of fields in a model goes up. 
     823The above example can be rewritten using ``update_or_create()`` like so:: 
     824 
     825    obj, created = Person.objects.update_or_create(first_name='John', last_name='Lennon', 
     826                       defaults={'birthday': date(1940, 10, 9)}) 
     827 
     828Any keyword arguments passed to ``update_or_create()`` will be used in a 
     829call to ``get_or_create()``. If ``get_or_create()`` creates an object, then 
     830nothing needs to be done by ``update_or_create()`` and a tuple of the created 
     831object and ``True`` is returned. If, on the other hand, ``get_or_create()`` 
     832does not create a new object, then ``update_or_create()`` will update the 
     833object with the values passed in the ``defaults`` parameter and a tuple of 
     834the updated object and ``True`` is returned. 
     835 
     836The ``defaults`` parameter should be a dict of attribute-value pairs that 
     837you want to update. If ``defaults`` is empty or not specified, then 
     838``update_or_create()`` will act exactly like ``get_or_create()`` since there 
     839would be nothing to update. 
     840 
     841As with ``get_or_create()``, if you need to use ``update_or_create()`` in a 
     842view, please make sure to use it only in ``POST`` requests unless you have a 
     843good reason not to. ``GET`` requests shouldn't have any effect on data; use 
     844``POST`` whenever a request to a page has a side effect on your data. For 
     845more, see `Safe methods`_ in the HTTP spec. 
     846 
     847.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1 
     848 
    787849``count()`` 
    788850~~~~~~~~~~~ 
    789851