2016-03-31 31 views
6

Mam plik modelu, który używa sygnału post_save do utworzenia połączonego wiersza w innej tabeli. W typowy sposób mogę utworzyć stronę z jednego z moich widoków ozdobionego @ transaction.atomic.Czy sygnały django są również zawarte w dekoratorze transaction.atomic?

Chciałbym wiedzieć, czy ten dekorator umieści obiekt strony i obiekt SharedPage w tej samej transakcji. Z dokumentacji django nie wynika, że ​​sygnały są częścią tej transakcji atomowej.

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

Odpowiedz

3

Tak sygnały są wysyłane z tej samej wartości dla ustawienia automatycznego zatwierdzania połączenia (który manipulowane przez transaction.commit dekorator), który służy do zapisania modelu. Odnosząc się kod w django.db.models.base.Model.save_base() metoda,

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) 

Jak widać, żaden specjalny kod jest napisane, aby zmienić ustawienia automatycznego zatwierdzania. Tak więc, jeśli twój widok deklaruje, że wszystkie elementy związane z bazą danych muszą zapewnić atomowość za pomocą @ transaction.atomic, to zmiany wprowadzone przez twój widok (albo model.save() lub przez procedury obsługi sygnałów) nie zostaną zatwierdzone, dopóki twój widok wykonanie jest zakończone.

Mam nadzieję, że może ci pomóc.

Powiązane problemy