#30022: Doc how to combine post_save signal with on_commit to alter a m2m 
relation
when saving a model instance
-------------------------------------+-------------------------------------
     Reporter:  George Tantiras      |                    Owner:  nobody
         Type:                       |                   Status:  closed
  Cleanup/optimization               |
    Component:  Documentation        |                  Version:  2.1
     Severity:  Normal               |               Resolution:  wontfix
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by George Tantiras):

 Replying to [comment:1 Simon Charette]:
 > `do_something()` would never be called because
 `validate_and_add_to_group()`'s `save()` calls that would trigger the
 `post_save` receiver would only queue the group additions to be performed
 `on_commit` which wouldn't happen until the `accept_group_invite` function
 exits.

 The above is very clear and understood.

 I made [https://github.com/raratiru/django-testing-on-commit an effort] to
 replicate the below quote:

 > If you want to make sure both `save()` and its `pre_save` and
 `post_save` side effects are performed in as an atomic operation (either
 succeed or fail) then you should simply wrap your `save()` calls in an
 `atomic` block.

 In my bare django project I plugged [https://github.com/raratiru/django-
 testing-on-commit/blob/master/user/signals.py user/signals.py] and
 [https://github.com/raratiru/django-testing-on-
 commit/blob/master/user/test_user.py user/test_user.py] to test under
 which circumstances the signal will successfully add the saved user
 instance to the 'Superuser' group.

 The result is that both `transaction_atomic()` and
 `transaction.on_commit()` are needed.

 I report this, just in case it is an unexpected behavior.

 {{{

 def test_user(group, user_data, superuser_data):
     '''
     If transaction.on_commit() is not used in the receiver, this test will
 fail.
     '''
     # Add a user
     creation_form = UserCreationForm(data=user_data)
     user = creation_form.save()
     # Make the new user a Superuser
     change_form = UserChangeForm(instance=user, data=superuser_data)
     with transaction.atomic():
         superuser = change_form.save()

     assert group in superuser.groups.all(), "Although is_superuser is
 True, the user is not in the Superuser group"


 def test_user_non_atomic(group, user_data, superuser_data):
     '''
     This will fail because transaction.atomic() is not used.
     '''
     creation_form = UserCreationForm(data=user_data)
     user = creation_form.save()
     change_form = UserChangeForm(instance=user, data=superuser_data)
     superuser = change_form.save()

     assert group in superuser.groups.all(), "Although is_superuser is
 True, the user is not in the Superuser group"
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30022#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.8a2e06cf41e0c6747c7eec5a824b1c2b%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to