I checked Django repository on GitHub. Then, transaction.atomic(using=using, savepoint=False) and transaction.mark_for_rollback_on_error(using=using) are called in save_base() which is called in save() in class Model(metaclass=ModelBase): as shown below:
# "django/django/db/models/base.py"
class Model(metaclass=ModelBase):
# ...
def save(
self, force_insert=False, force_update=False, using=None, update_fields=None
):
# ...
self.save_base(
using=using,
force_insert=force_insert,
force_update=force_update,
update_fields=update_fields,
)
# ...
def save_base(
self,
raw=False,
force_insert=False,
force_update=False,
using=None,
update_fields=None,
):
# ...
# A transaction isn't needed if one query is issued.
if meta.parents:
context_manager = transaction.atomic(using=using, savepoint=False) # Here
else:
context_manager = transaction.mark_for_rollback_on_error(using=using) # Here
with context_manager:
# ...
So, by default, transaction is already used for Django Admin, right?
So, in class Person(models.Model):
, if we override save()
which calls super().save(*args, **kwargs)` in it as shown below:
# "models.py"
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
super().save(*args, **kwargs) # Here
We don't need to put @transaction.atomic
on save()
as shown below, right?:
# "models.py"
from django.db import models
from django.db import transaction
class Person(models.Model):
name = models.CharField(max_length=30)
@transaction.atomic # Don't need
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
Or, we don't need to use with transaction.atomic():
in save()
as shown below, right?:
# "models.py"
from django.db import models
from django.db import transaction
class Person(models.Model):
name = models.CharField(max_length=30)
def save(self, *args, **kwargs):
with transaction.atomic(): # Don't need
super().save(*args, **kwargs)
Or, we don't need to set 'ATOMIC_REQUESTS': True
to database settings in settings.py
as shown below, right?:
# "settings.py"
DATABASES = {
'default':{
'ENGINE':'django.db.backends.postgresql',
'NAME':'postgres',
'USER':'postgres',
'PASSWORD':'admin',
'HOST':'localhost',
'PORT':'5432',
'ATOMIC_REQUESTS': True, # Here
}
}