django 信号是否也包含在 transaction.atomic 装饰器中? [英] Are django signals also included inside of the transaction.atomic decorator?

查看:48
本文介绍了django 信号是否也包含在 transaction.atomic 装饰器中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型文件,它使用 post_save 信号在另一个表中创建链接行.以典型的方式,我可以从我的一个视图中创建一个页面,该页面用 @transaction.atomic 装饰.

I have a model file that uses a post_save signal to create a linked row in another table. In typical fashion, I can create a page from one of my views which is decorated with @transaction.atomic.

我想知道这个装饰器是否会将 Page 对象和 SharedPage 对象的创建放在同一个事务中.从 Django 文档中并不清楚信号是这个原子事务的一部分.

I would like to know if this decorator will put the creation of the Page object and the SharedPage object in the same transaction. It is not clear from the django docs that signals are a part of this atomic transaction.

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() 方法中的代码,

Yes, signals are dispatched with the same value for autocommit setting of connection(which is tweaked by transaction.commit decorator), which is used to save model. Referring the code in django.db.models.base.Model.save_base() method,

    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() 或通过信号处理程序)所做的数据库更改不会提交,直到您的视图执行完毕.

As you can see, no special code is written to change autocommit settings. So, if your view declares that all the database-related stuff must ensure atomicity by using @transaction.atomic, then db changes made by your view(either model.save() or through signal handlers), is not committed, until your view execution is finished.

希望能帮到你.

这篇关于django 信号是否也包含在 transaction.atomic 装饰器中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆