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

查看:99
本文介绍了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.

我希望,它可能会对您有所帮助。

I hope, it may help you out.

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

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