django信号是否也包含在transaction.atomic装饰器内?

时间:2016-03-31 11:11:00

标签: python django django-models transactions django-signals

我有一个模型文件,它使用post_save信号在另一个表中创建一个链接行。以典型的方式,我可以使用@ transaction.atomic。

装饰我的一个视图创建一个页面

我想知道这个装饰器是否会在同一个事务中创建Page对象和SharedPage对象。从django docs中不清楚信号是这个原子事务的一部分。

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')

1 个答案:

答案 0 :(得分:8)

是的,使用相同的值来调度信号,用于连接的自动提交设置(由transaction.commit decorator调整),用于保存模型。参考django.db.models.base.Model.save_base()方法中的代码,

print('We pay your employees payroll!')    
while True:
    n = raw_input("\nEnter employee or Enter '0' to quit: ")
    if n.strip() == '0':
        break

    pr=float(input("Enter Payrate: "))
    hrs=float(input("Enter Hours Worked: "))

    if hrs <= 40:
        print("Hours Worked: ", hrs)
        print("Payrate: ", pr)
        print("Basepay:", hrs*pr)
    elif hrs > 40:
        print('Hours Worked: ', hrs)
        print("Payrate: ", pr)
        print("Overtime Rate: ", pr*1.5)
        print("Overtime Hours: ", hrs-40)
        print("Basepay: ", (hrs-40)*pr)
        print("Overtime Pay: ", (pr*1.5)*(hrs-40))
        print("Grosspay: ", (pr*1.5)*(hrs-40)+(pr*hrs))

print("Employees Paid, Goodbye!")

如您所见,没有编写特殊代码来更改自动提交设置。因此,如果您的视图声明所有与数据库相关的东西必须通过使用@ transaction.atomic确保原子性,那么您的视图(model.save()或通过信号处理程序)所做的db更改不会被提交,直到您的视图为止执行完毕。

我希望,它可以帮助你。