2016-03-31 8 views
6

post_save信号を使用して別のテーブルにリンクされた行を作成するモデルファイルがあります。典型的な方法では、私は@ transaction.atomicで装飾されている私のビューの1つからページを作成することができます。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の変更は、実行が終了する。

お手数ですが、お手数ですが、