diff options
| author | tschilling <schillingt@better-simple.com> | 2023-01-30 20:39:15 -0600 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2023-02-14 11:50:35 +0100 |
| commit | c5808470aaffda661cb911b06d5b848dd7b75467 (patch) | |
| tree | fd4e8b25bf9a7fee05cd61f27c6536a57f134a16 /django/db/models | |
| parent | ecafcaf634fcef93f9da8cb12795273dd1c3a576 (diff) | |
| download | django-c5808470aaffda661cb911b06d5b848dd7b75467.tar.gz | |
Fixed #34280 -- Allowed specifying different field values for create operation in QuerySet.update_or_create().
Diffstat (limited to 'django/db/models')
| -rw-r--r-- | django/db/models/query.py | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/django/db/models/query.py b/django/db/models/query.py index 9d621c4f69..71bb088679 100644 --- a/django/db/models/query.py +++ b/django/db/models/query.py @@ -926,25 +926,32 @@ class QuerySet(AltersData): **kwargs, ) - def update_or_create(self, defaults=None, **kwargs): + def update_or_create(self, defaults=None, create_defaults=None, **kwargs): """ Look up an object with the given kwargs, updating one with defaults - if it exists, otherwise create a new one. + if it exists, otherwise create a new one. Optionally, an object can + be created with different values than defaults by using + create_defaults. Return a tuple (object, created), where created is a boolean specifying whether an object was created. """ - defaults = defaults or {} + if create_defaults is None: + update_defaults = create_defaults = defaults or {} + else: + update_defaults = defaults or {} self._for_write = True with transaction.atomic(using=self.db): # Lock the row so that a concurrent update is blocked until # update_or_create() has performed its save. - obj, created = self.select_for_update().get_or_create(defaults, **kwargs) + obj, created = self.select_for_update().get_or_create( + create_defaults, **kwargs + ) if created: return obj, created - for k, v in resolve_callables(defaults): + for k, v in resolve_callables(update_defaults): setattr(obj, k, v) - update_fields = set(defaults) + update_fields = set(update_defaults) concrete_field_names = self.model._meta._non_pk_concrete_field_names # update_fields does not support non-concrete fields. if concrete_field_names.issuperset(update_fields): @@ -964,9 +971,10 @@ class QuerySet(AltersData): obj.save(using=self.db) return obj, False - async def aupdate_or_create(self, defaults=None, **kwargs): + async def aupdate_or_create(self, defaults=None, create_defaults=None, **kwargs): return await sync_to_async(self.update_or_create)( defaults=defaults, + create_defaults=create_defaults, **kwargs, ) |
