From 90af278203963e3e3f96e443971cd38a2dad34e4 Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Fri, 24 May 2013 16:36:09 -0400 Subject: [PATCH] Fixed #16137 - Removed kwargs requirement for QuerySet.get_or_create Thanks wilfred@, poirier, and charettes for work on the patch. --- django/db/models/query.py | 2 -- docs/ref/models/querysets.txt | 8 ++++++-- docs/releases/1.6.txt | 3 +++ tests/get_or_create/models.py | 5 +++++ tests/get_or_create/tests.py | 10 +++++++++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/django/db/models/query.py b/django/db/models/query.py index 71d432f7d5..5e8b3d995c 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -363,8 +363,6 @@ class QuerySet(object): Returns a tuple of (object, created), where created is a boolean specifying whether an object was created. """ - assert kwargs, \ - 'get_or_create() must be passed at least one keyword argument' defaults = kwargs.pop('defaults', {}) lookup = kwargs.copy() for f in self.model._meta.fields: diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 53359441ae..3fb5b3a498 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -1343,8 +1343,12 @@ get_or_create .. method:: get_or_create(**kwargs) -A convenience method for looking up an object with the given kwargs, creating -one if necessary. +A convenience method for looking up an object with the given kwargs (may be +empty if your model has defaults for all fields), creating one if necessary. + +.. versionchanged:: 1.6 + + Older versions of Django required ``kwargs``. Returns a tuple of ``(object, created)``, where ``object`` is the retrieved or created object and ``created`` is a boolean specifying whether a new object was diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 73b0fb85eb..4a8f7c6ecf 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -280,6 +280,9 @@ Minor features * The :exc:`~django.core.exceptions.DoesNotExist` exception now includes a message indicating the name of the attribute used for the lookup. +* The :meth:`~django.db.models.query.QuerySet.get_or_create` method no longer + requires at least one keyword argument. + Backwards incompatible changes in 1.6 ===================================== diff --git a/tests/get_or_create/models.py b/tests/get_or_create/models.py index 84c8fda968..1a85de2e74 100644 --- a/tests/get_or_create/models.py +++ b/tests/get_or_create/models.py @@ -21,6 +21,11 @@ class Person(models.Model): def __str__(self): return '%s %s' % (self.first_name, self.last_name) + +class DefaultPerson(models.Model): + first_name = models.CharField(max_length=100, default="Anonymous") + + class ManualPrimaryKeyTest(models.Model): id = models.IntegerField(primary_key=True) data = models.CharField(max_length=100) diff --git a/tests/get_or_create/tests.py b/tests/get_or_create/tests.py index 48f2a067c1..36c248b169 100644 --- a/tests/get_or_create/tests.py +++ b/tests/get_or_create/tests.py @@ -8,7 +8,7 @@ from django.db import IntegrityError, DatabaseError from django.utils.encoding import DjangoUnicodeDecodeError from django.test import TestCase, TransactionTestCase -from .models import Person, ManualPrimaryKeyTest, Profile, Tag, Thing +from .models import DefaultPerson, Person, ManualPrimaryKeyTest, Profile, Tag, Thing class GetOrCreateTests(TestCase): @@ -83,6 +83,14 @@ class GetOrCreateTests(TestCase): else: self.skipTest("This backend accepts broken utf-8.") + def test_get_or_create_empty(self): + # Regression test for #16137: get_or_create does not require kwargs. + try: + DefaultPerson.objects.get_or_create() + except AssertionError: + self.fail("If all the attributes on a model have defaults, we " + "shouldn't need to pass any arguments.") + class GetOrCreateTransactionTests(TransactionTestCase):