transaction.atomic 装饰器中是否也包含 django 信号?
Are django signals also included inside of the transaction.atomic decorator?
我有一个模型文件,它使用 post_save
信号在另一个 table 中创建链接行。以典型的方式,我可以从我的一个视图创建一个页面,该页面用 @transaction.atomic.
装饰
我想知道这个装饰器是否会将Page对象的创建和SharedPage对象的创建放在同一个事务中。从 django 文档中不清楚信号是这个原子事务的一部分。
models.py
class Page(models.Model):
name = models.CharField(default='My default page',max_length=200,blank=False)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
slug = models.SlugField()
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
is_public = models.BooleanField(default=False)
def __str__(self): # __unicode__ on Python 2
return self.name
class Meta:
ordering = ['position','created_at']
@receiver(post_save, sender=Page)
def create_shared_page_entry(sender, instance, created, **kwargs):
if created:
shared_page = SharedPage.objects.create(
page=instance,
user=instance.user,
can_edit=True
)
view.py
@require_http_methods(["POST"])
@transaction.atomic
def page_create(request):
name = request.POST.get('name')
page = Page.objects.create(name=name, owner=request.user)
data = serializers.serialize("json", [page])
return HttpResponse(data, content_type='application/json')
是的,为连接的自动提交设置发送相同的信号(由 transaction.commit 装饰器调整),用于保存模型。参考 django.db.models.base.Model.save_base() 方法中的代码,
if not meta.auto_created:
signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using, update_fields=update_fields)
with transaction.atomic(using=using, savepoint=False):
if not raw:
self._save_parents(cls, using, update_fields)
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
# Store the database on which the object was saved
self._state.db = using
# Once saved, this is no longer a to-be-added instance.
self._state.adding = False
# Signal that the save is complete
if not meta.auto_created:
signals.post_save.send(sender=origin, instance=self, created=(not updated),update_fields=update_fields, raw=raw, using=using)
如您所见,没有编写特殊代码来更改自动提交设置。因此,如果您的视图声明所有与数据库相关的内容都必须通过使用@transaction.atomic 来确保原子性,那么您的视图(model.save() 或通过信号处理程序)所做的数据库更改不会提交, 直到您的视图执行完成。
希望对您有所帮助。
我有一个模型文件,它使用 post_save
信号在另一个 table 中创建链接行。以典型的方式,我可以从我的一个视图创建一个页面,该页面用 @transaction.atomic.
我想知道这个装饰器是否会将Page对象的创建和SharedPage对象的创建放在同一个事务中。从 django 文档中不清楚信号是这个原子事务的一部分。
models.py
class Page(models.Model):
name = models.CharField(default='My default page',max_length=200,blank=False)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
slug = models.SlugField()
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
is_public = models.BooleanField(default=False)
def __str__(self): # __unicode__ on Python 2
return self.name
class Meta:
ordering = ['position','created_at']
@receiver(post_save, sender=Page)
def create_shared_page_entry(sender, instance, created, **kwargs):
if created:
shared_page = SharedPage.objects.create(
page=instance,
user=instance.user,
can_edit=True
)
view.py
@require_http_methods(["POST"])
@transaction.atomic
def page_create(request):
name = request.POST.get('name')
page = Page.objects.create(name=name, owner=request.user)
data = serializers.serialize("json", [page])
return HttpResponse(data, content_type='application/json')
是的,为连接的自动提交设置发送相同的信号(由 transaction.commit 装饰器调整),用于保存模型。参考 django.db.models.base.Model.save_base() 方法中的代码,
if not meta.auto_created:
signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using, update_fields=update_fields)
with transaction.atomic(using=using, savepoint=False):
if not raw:
self._save_parents(cls, using, update_fields)
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
# Store the database on which the object was saved
self._state.db = using
# Once saved, this is no longer a to-be-added instance.
self._state.adding = False
# Signal that the save is complete
if not meta.auto_created:
signals.post_save.send(sender=origin, instance=self, created=(not updated),update_fields=update_fields, raw=raw, using=using)
如您所见,没有编写特殊代码来更改自动提交设置。因此,如果您的视图声明所有与数据库相关的内容都必须通过使用@transaction.atomic 来确保原子性,那么您的视图(model.save() 或通过信号处理程序)所做的数据库更改不会提交, 直到您的视图执行完成。
希望对您有所帮助。