---
url: "https://vueda.dev/v3/reference/api/py/vueda.user.mixins/VUEDAPermissionsMixin.md"
title: "VUEDAPermissionsMixin"
---

# VUEDAPermissionsMixin

## Overview

Extends Django's ``PermissionsMixin`` with a multi-layer permission check:

1. Django model-level permissions (via ``super().has_perm``).
2. Workflow state permissions (grant or deny based on the object's current state).
3. Row-level permissions (``RowLevelPermissions.check_instance``).
4. Workflow-aware row-level permissions (``RowLevelPermissions.check_instance_workflow``),
   which run last and can override a state deny.

Superusers always return ``True`` and skip all checks.

## `Meta` {#Meta}

### Source {#Meta-source}

`server/vueda/user/mixins.py:36`

## `has_perm` {#has_perm}

Return True if the user has the specified permission. Query all
available auth backends, but return immediately if any backend returns
True. Thus, a user who has permission from a single auth backend is
assumed to have permission in general. If an object is provided, check
permissions for that object.

### Signature {#has_perm-signature}

`has_perm(self, perm, obj)`

#### Parameters {#has_perm-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| self |  | yes |  |  |
| <span id="has_perm-param-perm">perm</span> |  | yes |  |  |
| <span id="has_perm-param-obj">obj</span> | `django.db.models.base.Model \| None` | no | `None` |  |

#### Returns {#has_perm-returns}

`bool`

### Source {#has_perm-source}

`server/vueda/user/mixins.py:39`

## `is_superuser` {#is_superuser}

A wrapper for a deferred-loading field. When the value is read from this
object the first time, the query is executed.

### Signature {#is_superuser-signature}

`is_superuser(unknown)`

#### Parameters {#is_superuser-parameters}

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| <span id="is_superuser-param-unknown">unknown</span> |  | yes |  |  |

## `groups` {#groups}

Accessor to the related objects manager on the forward and reverse sides of
a many-to-many relation.

In the example::

    class Pizza(Model):
        toppings = ManyToManyField(Topping, related_name='pizzas')

``Pizza.toppings`` and ``Topping.pizzas`` are ``ManyToManyDescriptor``
instances.

Most of the implementation is delegated to a dynamically defined manager
class built by ``create_forward_many_to_many_manager()`` defined below.

## `user_permissions` {#user_permissions}

Accessor to the related objects manager on the forward and reverse sides of
a many-to-many relation.

In the example::

    class Pizza(Model):
        toppings = ManyToManyField(Topping, related_name='pizzas')

``Pizza.toppings`` and ``Topping.pizzas`` are ``ManyToManyDescriptor``
instances.

Most of the implementation is delegated to a dynamically defined manager
class built by ``create_forward_many_to_many_manager()`` defined below.

## Source

`server/vueda/user/mixins.py:23`
