drf-rules


Namedrf-rules JSON
Version 0.0.7 PyPI version JSON
download
home_pageNone
SummaryRules Permissions with Django DRF
upload_time2025-09-13 22:33:16
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8
licenseBSD-3-Clause
keywords django drf permissions rules
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            drf-rules
=========

.. image:: https://img.shields.io/pypi/v/drf-rules.svg
    :target: https://pypi.org/project/drf-rules
    :alt: PyPI - Version

.. image:: https://img.shields.io/pypi/pyversions/drf-rules.svg
    :target: https://pypi.org/project/drf-rules
    :alt: PyPI - Python Version

.. image:: https://coveralls.io/repos/github/lsaavedr/drf-rules/badge.svg
    :target: https://coveralls.io/github/lsaavedr/drf-rules
    :alt: Coverage Status

``drf-rules`` is a **Django REST Framework** extension built on top of
`django-rules`_ that provides **object-level permissions** fully aligned
with DRF actions.

It allows you to **declaratively define** which users or groups can perform
each action (*create, list, retrieve, update, destroy, etc.*) on your models
and API endpoints.

----

.. _django-rules: https://github.com/dfunckt/django-rules


Features
--------

- **Simplicity (KISS)**: minimal setup, easy to understand.
- **Native DRF integration**: rules map directly to DRF actions.
- **Consistent conventions**: follows DRF’s CRUD action names
  (``retrieve`` instead of ``view``, ``destroy`` instead of ``delete``).
- **Well tested and documented**: high test coverage and clear examples.
- **Powered by django-rules**: inherits its flexibility and extensibility.


Table of Contents
-----------------

- `Requirements`_
- `Installation`_
- `Django Setup`_
- `Defining Rules`_
- `Using with DRF`_
  + `Model Permissions`_
  + `View Permissions`_
  + `Custom User Integration`_
- `License`_


Requirements
------------

- Python **3.8+**
- Django **4.2+**

Note: `drf-rules` supports all currently maintained Django versions and drops
end-of-life versions in minor releases. See the Django Project documentation
for timelines.


Installation
------------

Using pip:

.. code-block:: console

    $ pip install drf-rules

Using uv:

.. code-block:: console

    $ uv add drf-rules

Run tests with:

.. code-block:: console

    $ ./runtests.sh


Django Setup
------------

Add ``rules`` to ``INSTALLED_APPS``:

.. code-block:: python

    INSTALLED_APPS = [
        # ...
        "rules",
    ]

Configure authentication backends:

.. code-block:: python

    AUTHENTICATION_BACKENDS = [
        "rules.permissions.ObjectPermissionBackend",
        "django.contrib.auth.backends.ModelBackend",
    ]


Defining Rules
--------------

Example with a ``Book`` model:

.. code-block:: python

    import rules

    @rules.predicate
    def is_librarian(user):
        return user.groups.filter(name="librarians").exists()

    @rules.predicate
    def is_author(user):
        return user.groups.filter(name="authors").exists()


Using with DRF
--------------

Model Permissions
.................

Define object-level rules in ``Meta.rules_permissions``:

.. code-block:: python

    import rules
    from rules.contrib.models import RulesModel

    class Book(RulesModel):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=100)

        class Meta:
            rules_permissions = {
                "create": rules.is_staff,
                "retrieve": rules.is_authenticated,
            }

CRUD conventions differ slightly:

.. list-table:: CRUD Conventions
   :header-rows: 1

   * - Action
     - django-rules
     - drf-rules
   * - Create
     - add
     - create
   * - Retrieve
     - view
     - retrieve
   * - Update
     - change
     - update / partial_update
   * - Delete
     - delete
     - destroy
   * - List
     - view
     - list


View Permissions
................

Use ``AutoRulesPermission`` with your DRF views:

.. code-block:: python

    from rest_framework.viewsets import ModelViewSet
    from drf_rules.permissions import AutoRulesPermission

    class BookViewSet(ModelViewSet):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        permission_classes = [AutoRulesPermission]

You can also define rules for **custom actions**:

.. code-block:: python

    class Book(RulesModel):
        title = models.CharField(max_length=100)
        author = models.CharField(max_length=100)

        class Meta:
            rules_permissions = {
                "create": rules.is_staff,
                "retrieve": rules.is_authenticated,
                "custom_nodetail": rules.is_authenticated,
                ":default:": rules.is_authenticated,
            }

- The ``:default:`` rule applies to all **conventional** actions
  (``list``, ``retrieve``, ``create``, ``update``, ``partial_update``,
  ``destroy``) not explicitly defined.
- Non-standard actions (e.g. ``custom_nodetail``) must be defined explicitly.


Custom User Integration
.......................

If you are using a **custom User model** or any other custom model, you can
integrate ``drf-rules`` by combining ``RulesModelMixin`` with the
``RulesModelBase`` metaclass.  This ensures that permissions are automatically
registered on the model.

.. code-block:: python

    from django.contrib.auth.models import AbstractUser
    from rules.contrib.models import RulesModelMixin, RulesModelBase

    class CustomUser(AbstractUser, RulesModelMixin, metaclass=RulesModelBase):
        """
        Example custom user integrated with drf-rules.
        You can define CRUD permissions here via Meta.rules_permissions.
        """
        class Meta:
            rules_permissions = {
                "create": rules.is_staff,
                "retrieve": rules.is_authenticated,
                ":default:": rules.is_authenticated,
            }

If you already use a **custom metaclass** for your user model (or any other
model), make sure it **inherits from ``RulesModelBase``** so that
``drf-rules`` can register permissions correctly.


License
-------

``drf-rules`` is distributed under the terms of the
`BSD-3-Clause <https://spdx.org/licenses/BSD-3-Clause.html>`_ license.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "drf-rules",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "django, drf, permissions, rules",
    "author": null,
    "author_email": "Luis Saavedra <luis94855510@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/72/83/000083a0a2c5644d819de7c6e613414c472ab8885ea614a628efd7939cb1/drf_rules-0.0.7.tar.gz",
    "platform": null,
    "description": "drf-rules\n=========\n\n.. image:: https://img.shields.io/pypi/v/drf-rules.svg\n    :target: https://pypi.org/project/drf-rules\n    :alt: PyPI - Version\n\n.. image:: https://img.shields.io/pypi/pyversions/drf-rules.svg\n    :target: https://pypi.org/project/drf-rules\n    :alt: PyPI - Python Version\n\n.. image:: https://coveralls.io/repos/github/lsaavedr/drf-rules/badge.svg\n    :target: https://coveralls.io/github/lsaavedr/drf-rules\n    :alt: Coverage Status\n\n``drf-rules`` is a **Django REST Framework** extension built on top of\n`django-rules`_ that provides **object-level permissions** fully aligned\nwith DRF actions.\n\nIt allows you to **declaratively define** which users or groups can perform\neach action (*create, list, retrieve, update, destroy, etc.*) on your models\nand API endpoints.\n\n----\n\n.. _django-rules: https://github.com/dfunckt/django-rules\n\n\nFeatures\n--------\n\n- **Simplicity (KISS)**: minimal setup, easy to understand.\n- **Native DRF integration**: rules map directly to DRF actions.\n- **Consistent conventions**: follows DRF\u2019s CRUD action names\n  (``retrieve`` instead of ``view``, ``destroy`` instead of ``delete``).\n- **Well tested and documented**: high test coverage and clear examples.\n- **Powered by django-rules**: inherits its flexibility and extensibility.\n\n\nTable of Contents\n-----------------\n\n- `Requirements`_\n- `Installation`_\n- `Django Setup`_\n- `Defining Rules`_\n- `Using with DRF`_\n  + `Model Permissions`_\n  + `View Permissions`_\n  + `Custom User Integration`_\n- `License`_\n\n\nRequirements\n------------\n\n- Python **3.8+**\n- Django **4.2+**\n\nNote: `drf-rules` supports all currently maintained Django versions and drops\nend-of-life versions in minor releases. See the Django Project documentation\nfor timelines.\n\n\nInstallation\n------------\n\nUsing pip:\n\n.. code-block:: console\n\n    $ pip install drf-rules\n\nUsing uv:\n\n.. code-block:: console\n\n    $ uv add drf-rules\n\nRun tests with:\n\n.. code-block:: console\n\n    $ ./runtests.sh\n\n\nDjango Setup\n------------\n\nAdd ``rules`` to ``INSTALLED_APPS``:\n\n.. code-block:: python\n\n    INSTALLED_APPS = [\n        # ...\n        \"rules\",\n    ]\n\nConfigure authentication backends:\n\n.. code-block:: python\n\n    AUTHENTICATION_BACKENDS = [\n        \"rules.permissions.ObjectPermissionBackend\",\n        \"django.contrib.auth.backends.ModelBackend\",\n    ]\n\n\nDefining Rules\n--------------\n\nExample with a ``Book`` model:\n\n.. code-block:: python\n\n    import rules\n\n    @rules.predicate\n    def is_librarian(user):\n        return user.groups.filter(name=\"librarians\").exists()\n\n    @rules.predicate\n    def is_author(user):\n        return user.groups.filter(name=\"authors\").exists()\n\n\nUsing with DRF\n--------------\n\nModel Permissions\n.................\n\nDefine object-level rules in ``Meta.rules_permissions``:\n\n.. code-block:: python\n\n    import rules\n    from rules.contrib.models import RulesModel\n\n    class Book(RulesModel):\n        title = models.CharField(max_length=100)\n        author = models.CharField(max_length=100)\n\n        class Meta:\n            rules_permissions = {\n                \"create\": rules.is_staff,\n                \"retrieve\": rules.is_authenticated,\n            }\n\nCRUD conventions differ slightly:\n\n.. list-table:: CRUD Conventions\n   :header-rows: 1\n\n   * - Action\n     - django-rules\n     - drf-rules\n   * - Create\n     - add\n     - create\n   * - Retrieve\n     - view\n     - retrieve\n   * - Update\n     - change\n     - update / partial_update\n   * - Delete\n     - delete\n     - destroy\n   * - List\n     - view\n     - list\n\n\nView Permissions\n................\n\nUse ``AutoRulesPermission`` with your DRF views:\n\n.. code-block:: python\n\n    from rest_framework.viewsets import ModelViewSet\n    from drf_rules.permissions import AutoRulesPermission\n\n    class BookViewSet(ModelViewSet):\n        queryset = Book.objects.all()\n        serializer_class = BookSerializer\n        permission_classes = [AutoRulesPermission]\n\nYou can also define rules for **custom actions**:\n\n.. code-block:: python\n\n    class Book(RulesModel):\n        title = models.CharField(max_length=100)\n        author = models.CharField(max_length=100)\n\n        class Meta:\n            rules_permissions = {\n                \"create\": rules.is_staff,\n                \"retrieve\": rules.is_authenticated,\n                \"custom_nodetail\": rules.is_authenticated,\n                \":default:\": rules.is_authenticated,\n            }\n\n- The ``:default:`` rule applies to all **conventional** actions\n  (``list``, ``retrieve``, ``create``, ``update``, ``partial_update``,\n  ``destroy``) not explicitly defined.\n- Non-standard actions (e.g. ``custom_nodetail``) must be defined explicitly.\n\n\nCustom User Integration\n.......................\n\nIf you are using a **custom User model** or any other custom model, you can\nintegrate ``drf-rules`` by combining ``RulesModelMixin`` with the\n``RulesModelBase`` metaclass.  This ensures that permissions are automatically\nregistered on the model.\n\n.. code-block:: python\n\n    from django.contrib.auth.models import AbstractUser\n    from rules.contrib.models import RulesModelMixin, RulesModelBase\n\n    class CustomUser(AbstractUser, RulesModelMixin, metaclass=RulesModelBase):\n        \"\"\"\n        Example custom user integrated with drf-rules.\n        You can define CRUD permissions here via Meta.rules_permissions.\n        \"\"\"\n        class Meta:\n            rules_permissions = {\n                \"create\": rules.is_staff,\n                \"retrieve\": rules.is_authenticated,\n                \":default:\": rules.is_authenticated,\n            }\n\nIf you already use a **custom metaclass** for your user model (or any other\nmodel), make sure it **inherits from ``RulesModelBase``** so that\n``drf-rules`` can register permissions correctly.\n\n\nLicense\n-------\n\n``drf-rules`` is distributed under the terms of the\n`BSD-3-Clause <https://spdx.org/licenses/BSD-3-Clause.html>`_ license.\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "Rules Permissions with Django DRF",
    "version": "0.0.7",
    "project_urls": {
        "Documentation": "https://github.com/lsaavedr/drf-rules#readme",
        "Issues": "https://github.com/lsaavedr/drf-rules/issues",
        "Source": "https://github.com/lsaavedr/drf-rules"
    },
    "split_keywords": [
        "django",
        " drf",
        " permissions",
        " rules"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "86ff307fb48a8280881c0eb15272f75dcc715888a57aae35885739d15e101ad0",
                "md5": "449fe906c96d7aee8674275016adacc5",
                "sha256": "cad26bd2adae930c66f2dcb680fbb848d0c33ff4e2fe0181bb666915d926d9a6"
            },
            "downloads": -1,
            "filename": "drf_rules-0.0.7-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "449fe906c96d7aee8674275016adacc5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 7853,
            "upload_time": "2025-09-13T22:33:15",
            "upload_time_iso_8601": "2025-09-13T22:33:15.084279Z",
            "url": "https://files.pythonhosted.org/packages/86/ff/307fb48a8280881c0eb15272f75dcc715888a57aae35885739d15e101ad0/drf_rules-0.0.7-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7283000083a0a2c5644d819de7c6e613414c472ab8885ea614a628efd7939cb1",
                "md5": "778d0c0f19442db132f2c57fa4bad2f8",
                "sha256": "4a737b80e6315265a1d38ae432b57e2c9f3ddbdea5e0f75864c3a12839f8b99e"
            },
            "downloads": -1,
            "filename": "drf_rules-0.0.7.tar.gz",
            "has_sig": false,
            "md5_digest": "778d0c0f19442db132f2c57fa4bad2f8",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 37871,
            "upload_time": "2025-09-13T22:33:16",
            "upload_time_iso_8601": "2025-09-13T22:33:16.636970Z",
            "url": "https://files.pythonhosted.org/packages/72/83/000083a0a2c5644d819de7c6e613414c472ab8885ea614a628efd7939cb1/drf_rules-0.0.7.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-13 22:33:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "lsaavedr",
    "github_project": "drf-rules#readme",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "drf-rules"
}
        
Elapsed time: 2.51437s