Ticket #3121: get_or_create.diff

File get_or_create.diff, 3.7 KB (added by Jan Rademaker <j.rademaker@…>, 16 years ago)

Patch + tests

  • django/db/models/fields/related.py

     
    226226                return new_obj
    227227            create.alters_data = True
    228228
     229            def get_or_create(self, **kwargs):
     230                assert len(kwargs), 'get_or_create() must be passed at least one keyword argument'
     231                defaults = kwargs.pop('defaults', {})
     232                try:
     233                    return self.get(**kwargs), False
     234                except self.model.DoesNotExist:
     235                    params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
     236                    params.update(defaults)
     237                    obj = self.create(**params)
     238                    return obj, True
     239            get_or_create.alters_data = True
     240
    229241            # remove() and clear() are only provided if the ForeignKey can have a value of null.
    230242            if rel_field.null:
    231243                def remove(self, *objs):
     
    314326            return new_obj
    315327        create.alters_data = True
    316328
     329        def get_or_create(self, **kwargs):
     330            assert len(kwargs), 'get_or_create() must be passed at least one keyword argument'
     331            defaults = kwargs.pop('defaults', {})
     332            try:
     333                return self.get(**kwargs), False
     334            except self.model.DoesNotExist:
     335                params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
     336                params.update(defaults)
     337                obj = self.create(**params)
     338                return obj, True
     339        get_or_create.alters_data = True
     340
    317341        def _add_items(self, source_col_name, target_col_name, *objs):
    318342            # join_table: name of the m2m link table
    319343            # source_col_name: the PK colname in join_table for the source object
  • tests/modeltests/get_or_create/models.py

     
    1515    def __unicode__(self):
    1616        return u'%s %s' % (self.first_name, self.last_name)
    1717
     18class Publisher(models.Model):
     19    name = models.CharField(maxlength=100)
     20
     21class Author(models.Model):
     22    name = models.CharField(maxlength=100)
     23
     24class Book(models.Model):
     25    name = models.CharField(maxlength=100)
     26    authors = models.ManyToManyField(Author, related_name='books')
     27    publisher = models.ForeignKey(Publisher, related_name='books')
     28
    1829__test__ = {'API_TESTS':"""
    1930# Acting as a divine being, create an Person.
    2031>>> from datetime import date
     
    4960False
    5061>>> Person.objects.count()
    51622
     63
     64# First create a Publisher.
     65>>> p = Publisher.objects.create(name='Acme Publishing')
     66
     67# Create a book, it should be created.
     68>>> book, created = p.books.get_or_create(name='The Book of Ed & Fred')
     69>>> created
     70True
     71
     72# Try again.
     73>>> book, created = p.books.get_or_create(name='The Book of Ed & Fred')
     74>>> created
     75False
     76
     77# A book needs Authors.
     78>>> ed, created = book.authors.get_or_create(name='Ed')
     79>>> fred, created = book.authors.get_or_create(name='Fred')
     80
     81# Add another Author, without any books.
     82>>> Author.objects.create(name='Ted')
     83<Author: Author object>
     84
     85# By now, there should be 3 Authors in total. The `book' object should have
     86# two.
     87>>> Author.objects.count()
     883
     89>>> book.authors.count()
     902
     91
     92# Ed writes another Book.
     93>>> ed.books.get_or_create(name="Ed's Recipies", publisher=p)
     94(<Book: Book object>, True)
     95
     96# Now Ed has two Books, Fred just one.
     97>>> ed.books.count()
     982
     99>>> fred.books.count()
     1001
    52101"""}
Back to Top