mirror of
https://github.com/django/django.git
synced 2025-10-30 00:56:09 +00:00
Fixed #32095 -- Made QuerySet.update_or_create() save only fields passed in defaults or with custom pre_save().
Thanks Florian Apolloner for the initial patch.
This commit is contained in:
committed by
Mariusz Felisiak
parent
1d77b931f7
commit
6cc0f22a73
@@ -20,7 +20,7 @@ from django.db import (
|
||||
router,
|
||||
transaction,
|
||||
)
|
||||
from django.db.models import AutoField, DateField, DateTimeField, sql
|
||||
from django.db.models import AutoField, DateField, DateTimeField, Field, sql
|
||||
from django.db.models.constants import LOOKUP_SEP, OnConflict
|
||||
from django.db.models.deletion import Collector
|
||||
from django.db.models.expressions import Case, F, Ref, Value, When
|
||||
@@ -963,7 +963,25 @@ class QuerySet:
|
||||
return obj, created
|
||||
for k, v in resolve_callables(defaults):
|
||||
setattr(obj, k, v)
|
||||
obj.save(using=self.db)
|
||||
|
||||
update_fields = set(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):
|
||||
# Add fields which are set on pre_save(), e.g. auto_now fields.
|
||||
# This is to maintain backward compatibility as these fields
|
||||
# are not updated unless explicitly specified in the
|
||||
# update_fields list.
|
||||
for field in self.model._meta.local_concrete_fields:
|
||||
if not (
|
||||
field.primary_key or field.__class__.pre_save is Field.pre_save
|
||||
):
|
||||
update_fields.add(field.name)
|
||||
if field.name != field.attname:
|
||||
update_fields.add(field.attname)
|
||||
obj.save(using=self.db, update_fields=update_fields)
|
||||
else:
|
||||
obj.save(using=self.db)
|
||||
return obj, False
|
||||
|
||||
async def aupdate_or_create(self, defaults=None, **kwargs):
|
||||
|
||||
Reference in New Issue
Block a user