Fixed #28222 -- Allowed settable properties in QuerySet.update_or_create()/get_or_create() defaults.

This commit is contained in:
Alex
2017-05-19 06:40:43 -04:00
committed by Tim Graham
parent 385cf7091e
commit 37ab3c3f9d
5 changed files with 38 additions and 5 deletions

View File

@@ -32,6 +32,18 @@ class Thing(models.Model):
name = models.CharField(max_length=255)
tags = models.ManyToManyField(Tag)
@property
def capitalized_name_property(self):
return self.name
@capitalized_name_property.setter
def capitalized_name_property(self, val):
self.name = val.capitalize()
@property
def name_in_all_caps(self):
return self.name.upper()
class Publisher(models.Model):
name = models.CharField(max_length=100)

View File

@@ -73,6 +73,11 @@ class GetOrCreateTests(TestCase):
"""
Thing.objects.get_or_create(pk=1)
def test_get_or_create_with_model_property_defaults(self):
"""Using a property with a setter implemented is allowed."""
t, _ = Thing.objects.get_or_create(defaults={'capitalized_name_property': 'annie'}, pk=1)
self.assertEqual(t.name, 'Annie')
def test_get_or_create_on_related_manager(self):
p = Publisher.objects.create(name="Acme Publishing")
# Create a book through the publisher.
@@ -328,6 +333,11 @@ class UpdateOrCreateTests(TestCase):
"""
Thing.objects.update_or_create(pk=1)
def test_update_or_create_with_model_property_defaults(self):
"""Using a property with a setter implemented is allowed."""
t, _ = Thing.objects.get_or_create(defaults={'capitalized_name_property': 'annie'}, pk=1)
self.assertEqual(t.name, 'Annie')
def test_error_contains_full_traceback(self):
"""
update_or_create should raise IntegrityErrors with the full traceback.
@@ -514,3 +524,11 @@ class InvalidCreateArgumentsTests(SimpleTestCase):
def test_multiple_invalid_fields(self):
with self.assertRaisesMessage(FieldError, "Invalid field name(s) for model Thing: 'invalid', 'nonexistent'"):
Thing.objects.update_or_create(name='a', nonexistent='b', defaults={'invalid': 'c'})
def test_property_attribute_without_setter_defaults(self):
with self.assertRaisesMessage(FieldError, "Invalid field name(s) for model Thing: 'name_in_all_caps'"):
Thing.objects.update_or_create(name='a', defaults={'name_in_all_caps': 'FRANK'})
def test_property_attribute_without_setter_kwargs(self):
with self.assertRaisesMessage(FieldError, "Invalid field name(s) for model Thing: 'name_in_all_caps'"):
Thing.objects.update_or_create(name_in_all_caps='FRANK', defaults={'name': 'Frank'})