Commit 5f979007 authored by Tim Graham's avatar Tim Graham
Browse files

Fixed #20834 -- Described how caching of user permissions works.

Thanks Giggaflop and Jennifer Casavantes.
parent 4416aa1d
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -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