diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 247f5a38f1..bfac4c922e 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -249,6 +249,39 @@ The permission can then be assigned to a attribute or to a :class:`~django.contrib.auth.models.Group` via its ``permissions`` attribute. +Permission caching +------------------ + +The :class:`~django.contrib.auth.backends.ModelBackend` caches permissions on +the ``User`` object after the first time they need to be fetched for a +permissions check. This is typically fine for the request-response cycle since +permissions are not typically checked immediately after they are added (in the +admin, for example). If you are adding permissions and checking them immediately +afterward, in a test or view for example, the easiest solution is to re-fetch +the ``User`` from the database. For example:: + + from django.contrib.auth.models import Permission, User + from django.shortcuts import get_object_or_404 + + def user_gains_perms(request, user_id): + user = get_object_or_404(User, pk=user_id) + # any permission check will cache the current set of permissions + user.has_perm('myapp.change_bar') + + permission = Permission.objects.get(codename='change_bar') + user.user_permissions.add(permission) + + # Checking the cached permission set + user.has_perm('myapp.change_bar') # False + + # Request new instance of User + user = get_object_or_404(User, pk=user_id) + + # Permission cache is repopulated from the database + user.has_perm('myapp.change_bar') # True + + ... + .. _auth-web-requests: Authentication in Web requests