#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.