Refs #31046 -- Added django.db.models.utils.resolve_callables().

This commit is contained in:
Baptiste Mispelon 2019-11-29 17:30:01 +01:00 committed by Mariusz Felisiak
parent c90ab30fa1
commit 6c0341f127
2 changed files with 13 additions and 3 deletions

View File

@ -23,6 +23,7 @@ from django.db.models.fields import AutoField
from django.db.models.functions import Cast, Trunc from django.db.models.functions import Cast, Trunc
from django.db.models.query_utils import FilteredRelation, Q from django.db.models.query_utils import FilteredRelation, Q
from django.db.models.sql.constants import CURSOR, GET_ITERATOR_CHUNK_SIZE from django.db.models.sql.constants import CURSOR, GET_ITERATOR_CHUNK_SIZE
from django.db.models.utils import resolve_callables
from django.db.utils import NotSupportedError from django.db.utils import NotSupportedError
from django.utils import timezone from django.utils import timezone
from django.utils.functional import cached_property, partition from django.utils.functional import cached_property, partition
@ -591,8 +592,8 @@ class QuerySet:
obj, created = self._create_object_from_params(kwargs, params, lock=True) obj, created = self._create_object_from_params(kwargs, params, lock=True)
if created: if created:
return obj, created return obj, created
for k, v in defaults.items(): for k, v in resolve_callables(defaults):
setattr(obj, k, v() if callable(v) else v) setattr(obj, k, v)
obj.save(using=self.db) obj.save(using=self.db)
return obj, False return obj, False
@ -603,7 +604,7 @@ class QuerySet:
""" """
try: try:
with transaction.atomic(using=self.db): with transaction.atomic(using=self.db):
params = {k: v() if callable(v) else v for k, v in params.items()} params = dict(resolve_callables(params))
obj = self.create(**params) obj = self.create(**params)
return obj, True return obj, True
except IntegrityError as e: except IntegrityError as e:

View File

@ -19,3 +19,12 @@ def make_model_tuple(model):
"Invalid model reference '%s'. String model references " "Invalid model reference '%s'. String model references "
"must be of the form 'app_label.ModelName'." % model "must be of the form 'app_label.ModelName'." % model
) )
def resolve_callables(mapping):
"""
Generate key/value pairs for the given mapping where the values are
evaluated if they're callable.
"""
for k, v in mapping.items():
yield k, v() if callable(v) else v