2016-03-31 31 views
6

Başka bir tabloda bağlantılı bir satır oluşturmak için post_save sinyalini kullanan bir model dosyanız var. Tipik bir şekilde, @ transaction.atomic ile dekore edilmiş görünümlerimden bir sayfa oluşturabilirim.Django sinyalleri de işlemin içinde yer alır.atomik dekoratör?

Bu dekoratörün, Sayfa nesnesinin ve SharedPage nesnesinin oluşturulmasını aynı işlemde oluşturup koymayacağını bilmek istiyorum. Django dokümanlarından, sinyallerin bu atomik işlemin bir parçası olduğu net değildir.

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

cevap

3

Evet sinyaller transaction.commit ile tweaked bağlantının autocommit ayarı için aynı değere (ile gönderilir modeli kaydetmek için kullanılan dekoratör). Gördüğünüz gibi, hiçbir özel kod autocommit ayarlarını değiştirmek için yazılır django.db.models.base.Model.save_base kodu() yöntemini,

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) 

değinen. Bu nedenle, görünümünüz tüm veritabanı ile ilgili maddelerin @ transaction.atomic kullanarak atomisiteyi sağlaması gerektiğini beyan ederse, görünümünüzün (ya da model.save() ya da sinyal işleyicilerinden) yapılan db değişiklikleri, görünümünüze kadar işlenmez. yürütme bitti.

Umarım, size yardımcı olabilir.