Skip to content

Utilities

django-guardian helper functions.

Unstable API

Functions defined within this module should be considered as django-guardian’s internal functionality. They are not guaranteed to be stable, and their APIs may change in any future releases.

get_anonymous_user()

Get the django-guardian equivalent of the anonymous user.

It returns a User model instance (not AnonymousUser) depending on ANONYMOUS_USER_NAME configuration.

See Also

See the configuration docs that explain that the Guardian anonymous user is not equivalent to Django’s AnonymousUser.

Source code in guardian/utils.py
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def get_anonymous_user() -> Any:
    """Get the django-guardian equivalent of the anonymous user.

    It returns a `User` model instance (not `AnonymousUser`) depending on
    `ANONYMOUS_USER_NAME` configuration.

    See Also:
        See the configuration docs that explain that the Guardian anonymous user is
        not equivalent to Django’s AnonymousUser.

        - [Guardian Configuration](https://django-guardian.readthedocs.io/en/stable/configuration.html)
        - [ANONYMOUS_USER_NAME configuration](https://django-guardian.readthedocs.io/en/stable/configuration.html#anonymous-user-nam)
    """
    user_model = get_user_model()
    lookup = {user_model.USERNAME_FIELD: guardian_settings.ANONYMOUS_USER_NAME}  # type: ignore[attr-defined]
    return user_model.objects.get(**lookup)

get_identity(identity)

Get a tuple with the identity of the given input.

Returns a tuple with one of the members set to None depending on whether the input is a Group instance or a User instance. Also accepts AnonymousUser instance but would return User instead. It is convenient and needed for authorization backend to support anonymous users.

Returns:

Type Description
tuple[Union[Any, None], Union[Any, None]]

Either (user_obj, None) or (None, group_obj) depending on the input type.

Parameters:

Name Type Description Default
identity User | Group

Instance of User or Group to get identity from.

required

Raises:

Type Description
NotUserNorGroup

If the function cannot return proper identity instance

Examples:

>>> from django.contrib.auth.models import User, Group
>>> user = User.objects.create(username='joe')
>>> get_identity(user)
(<User: joe>, None)

>>> group = Group.objects.create(name='users')
>>> get_identity(group)
(None, <Group: users>)

>>> anon = AnonymousUser()
>>> get_identity(anon)
(<User: AnonymousUser>, None)

>>> get_identity("not instance")
...
NotUserNorGroup: User/AnonymousUser or Group instance is required (got )
Source code in guardian/utils.py
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def get_identity(identity: Model) -> tuple[Union[Any, None], Union[Any, None]]:
    """Get a tuple with the identity of the given input.

    Returns a tuple with one of the members set to `None` depending on whether the input is
    a `Group` instance or a `User` instance.
    Also accepts AnonymousUser instance but would return `User` instead.
    It is convenient and needed for authorization backend to support anonymous users.

    Returns:
         Either (user_obj, None) or (None, group_obj) depending on the input type.

    Parameters:
        identity (User | Group): Instance of `User` or `Group` to get identity from.

    Raises:
        NotUserNorGroup: If the function cannot return proper identity instance

    Examples:
        ```shell
        >>> from django.contrib.auth.models import User, Group
        >>> user = User.objects.create(username='joe')
        >>> get_identity(user)
        (<User: joe>, None)

        >>> group = Group.objects.create(name='users')
        >>> get_identity(group)
        (None, <Group: users>)

        >>> anon = AnonymousUser()
        >>> get_identity(anon)
        (<User: AnonymousUser>, None)

        >>> get_identity("not instance")
        ...
        NotUserNorGroup: User/AnonymousUser or Group instance is required (got )
        ```
    """
    if isinstance(identity, AnonymousUser):
        identity = get_anonymous_user()

    group_model = get_group_obj_perms_model().group.field.related_model  # type: ignore[attr-defined]

    # get identity from queryset model type
    if isinstance(identity, QuerySet):
        identity_model_type = identity.model
        if identity_model_type == get_user_model():
            return identity, None
        elif identity_model_type == group_model:
            return None, identity

    # get identity from the first element in the list
    if isinstance(identity, list) and isinstance(identity[0], get_user_model()):
        return identity, None
    if isinstance(identity, list) and isinstance(identity[0], group_model):
        return None, identity

    if isinstance(identity, get_user_model()):
        return identity, None
    if isinstance(identity, group_model):
        return None, identity

    raise NotUserNorGroup("User/AnonymousUser or Group instance is required "
                          "(got %s)" % identity)

clean_orphan_obj_perms()

Seeks and removes all object permissions entries pointing at non-existing targets.

Returns:

Type Description
int

The number of objects removed.

Source code in guardian/utils.py
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def clean_orphan_obj_perms() -> int:
    """Seeks and removes all object permissions entries pointing at non-existing targets.

    Returns:
         The number of objects removed.
    """
    UserObjectPermission = get_user_obj_perms_model()
    GroupObjectPermission = get_group_obj_perms_model()

    deleted = 0
    # TODO: optimise
    for perm in chain(
        UserObjectPermission.objects.all().iterator(),
        GroupObjectPermission.objects.all().iterator(),
    ):
        if perm.content_object is None:
            logger.debug("Removing %s (pk=%d)" % (perm, perm.pk))
            perm.delete()
            deleted += 1
    logger.info("Total removed orphan object permissions instances: %d" %
                deleted)
    return deleted