Django

Code

Changeset 3092

Show
Ignore:
Timestamp:
06/06/06 19:09:29 (2 years ago)
Author:
adrian
Message:

Added Manager.get_or_create()

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/db/models/manager.py

    r2850 r3092  
    6666        return self.get_query_set().get(*args, **kwargs) 
    6767 
     68    def get_or_create(self, *args, **kwargs): 
     69        return self.get_query_set().get_or_create(*args, **kwargs) 
     70 
    6871    def filter(self, *args, **kwargs): 
    6972        return self.get_query_set().filter(*args, **kwargs) 
  • django/trunk/django/db/models/query.py

    r3073 r3092  
    205205        assert len(obj_list) == 1, "get() returned more than one %s -- it returned %s! Lookup parameters were %s" % (self.model._meta.object_name, len(obj_list), kwargs) 
    206206        return obj_list[0] 
     207 
     208    def get_or_create(self, **kwargs): 
     209        """ 
     210        Looks up an object with the given kwargs, creating one if necessary. 
     211        Returns a tuple of (object, created), where created is a boolean 
     212        specifying whether an object was created. 
     213        """ 
     214        assert len(kwargs), 'get_or_create() must be passed at least one keyword argument' 
     215        defaults = kwargs.pop('defaults', {}) 
     216        try: 
     217            return self.get(**kwargs), False 
     218        except self.model.DoesNotExist: 
     219            params = dict([(k, v) for k, v in kwargs.items() if '__' not in k]) 
     220            params.update(defaults) 
     221            obj = self.model(**params) 
     222            obj.save() 
     223            return obj, True 
    207224 
    208225    def latest(self, field_name=None): 
  • django/trunk/docs/db-api.txt

    r3073 r3092  
    706706        print "Either the entry or blog doesn't exist." 
    707707 
     708``get_or_create(**kwargs)`` 
     709~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     710 
     711A convenience method for looking up an object with the given kwargs, creating 
     712one if necessary. 
     713 
     714Returns a tuple of ``(object, created)``, where ``object`` is the retrieved or 
     715created object and ``created`` is a boolean specifying whether a new object was 
     716created. 
     717 
     718This is meant as a shortcut to boilerplatish code. For example:: 
     719 
     720    try: 
     721        obj = Person.objects.get(first_name='John', last_name='Lennon') 
     722    except Person.DoesNotExist: 
     723        obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9)) 
     724        obj.save() 
     725 
     726This pattern gets quite unwieldy as the number of fields in a model goes up. 
     727The above example can be rewritten using ``get_or_create()`` like so:: 
     728 
     729    obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon', 
     730                      defaults={'birthday': date(1940, 10, 9)}) 
     731 
     732Any keyword arguments passed to ``get_or_create()`` -- *except* an optional one 
     733called ``default`` -- will be used in a ``get()`` call. If an object is found, 
     734``get_or_create()`` returns a tuple of that object and ``False``. If an object 
     735is *not* found, ``get_or_create()`` will instantiate and save a new object, 
     736returning a tuple of the new object and ``True``. The new object will be 
     737created according to this algorithm:: 
     738 
     739    defaults = kwargs.pop('defaults', {}) 
     740    params = dict([(k, v) for k, v in kwargs.items() if '__' not in k]) 
     741    params.update(defaults) 
     742    obj = self.model(**params) 
     743    obj.save() 
     744 
     745In English, that means start with any non-``'defaults'`` keyword argument that 
     746doesn't contain a double underscore (which would indicate a non-exact lookup). 
     747Then add the contents of ``defaults``, overriding any keys if necessary, and 
     748use the result as the keyword arguments to the model class. 
     749 
     750Finally, if you have a field named ``defaults`` and want to use it as an exact 
     751lookup in ``get_or_create()``, just use ``'defaults__exact'``, like so:: 
     752 
     753    Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'}) 
     754 
    708755``count()`` 
    709756~~~~~~~~~~~