2016-03-31 53 views
6

我有一個模型文件,它使用post_save信號在另一個表中創建鏈接的行。以典型的方式,我可以從我的一個視圖創建一個頁面,用@ transaction.atomic進行裝飾。django信號是否也包含在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') 

回答

3

是,信號被分派有用於連接的自動提交設定爲相同的值(其由器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()或通過信號處理器)所做的db更改不會被提交,直到你的視圖執行完成。

我希望它可以幫助你。

相關問題