Registry / web-framework / djangorestframework-role-filters

djangorestframework-role-filters

JSON →
library1.1.0pypypi✓ verified 23d ago

djangorestframework-role-filters is a Python library that provides simple and declarative role-based filtering for Django REST Framework views and querysets. It aims to eliminate the need for verbose 'if-else' statements in view logic by centralizing role definitions. The current version is 1.1.0, with releases occurring periodically, typically to update compatibility with newer Django/DRF versions.

pip install djangorestframework-role-filters
INSTALL
IMPORT
SIG · DJANGORESTFRAMEWOR
D
djangorestframework-role-filters
web-frameworkpythonv1.1.0
Install
3.6s avg
Import
Disk
70MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v1.1.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.000s · 70.6MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 3.6s · import 0.000s · 71MB
70MB installed
● package 70MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

RoleFilter
from rest_framework_role_filters.role_filters import RoleFilter
Base class for defining role-specific filtering logic.
RoleFilterModelViewSet
from rest_framework_role_filters.viewsets import RoleFilterModelViewSet
Viewset that integrates role-based filtering.

This quickstart demonstrates how to define role-specific filters using `RoleFilter` subclasses and apply them to a `RoleFilterModelViewSet`. Each `RoleFilter` defines allowed actions, queryset filtering, and serializer classes based on a `role_id`. The `get_role_id` method on the `ViewSet` dynamically determines the user's role.

import os from django.db import models from django.contrib.auth.models import AbstractUser from rest_framework import serializers from rest_framework_role_filters.role_filters import RoleFilter from rest_framework_role_filters.viewsets import RoleFilterModelViewSet # --- Mock Django Setup (for runnable example) --- # This is usually handled by a real Django project setup os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings') # Replace with your actual settings import django django.setup() # --- Mock Models --- class User(AbstractUser): ROLE_CHOICES = ( ('admin', 'Admin'), ('user', 'User'), ) role = models.CharField(max_length=10, choices=ROLE_CHOICES, default='user') class Post(models.Model): title = models.CharField(max_length=255) body = models.TextField() user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.title # --- Mock Serializers --- class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ['id', 'title', 'body', 'user', 'created_at', 'updated_at'] read_only_fields = ['user'] class PostSerializerForUser(serializers.ModelSerializer): class Meta: model = Post fields = ['id', 'title', 'body', 'created_at', 'updated_at'] read_only_fields = ['user'] # --- Role Filters (role_filters.py) --- class AdminRoleFilter(RoleFilter): role_id = 'admin' def get_allowed_actions(self, request, view, obj=None): # Admins can do anything return ['create', 'list', 'retrieve', 'update', 'partial_update', 'destroy'] def get_queryset(self, request, view, queryset): # Admins see all posts return queryset.all() def get_serializer_class(self, request, view): return PostSerializer class UserRoleFilter(RoleFilter): role_id = 'user' def get_allowed_actions(self, request, view, obj=None): # Users can create, list, retrieve, update their own posts return ['create', 'list', 'retrieve', 'update', 'partial_update'] def get_queryset(self, request, view, queryset): # Users only see their own posts return queryset.filter(user=request.user) def get_serializer_class(self, request, view): return PostSerializerForUser def get_serializer(self, request, view, serializer_class, *args, **kwargs): # Example of dynamically modifying serializer fields for a user role fields = ('body', 'created_at', 'id', 'title', 'updated_at') return serializer_class(*args, fields=fields, **kwargs) # --- ViewSet (views.py) --- class PostViewSet(RoleFilterModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer role_filter_classes = [AdminRoleFilter, UserRoleFilter] def get_role_id(self, request): # This method is crucial: it determines the role for the current request # In a real app, request.user would be an authenticated user object. # For this example, we assume request.user has a 'role' attribute. # You might use request.user.is_staff or custom logic here. if request.user.is_authenticated: return request.user.role return 'anonymous' # Fallback or specific anonymous role def perform_create(self, serializer): serializer.save(user=self.request.user) # Example usage (not directly runnable without Django/DRF server): # from rest_framework.test import APIRequestFactory # from django.contrib.auth.models import AnonymousUser # # factory = APIRequestFactory() # # # Simulate an admin user # admin_user = User(username='admin', role='admin', is_authenticated=True) # request = factory.get('/posts/') # request.user = admin_user # view = PostViewSet.as_view({'get': 'list'}) # response = view(request) # print(f"Admin response status: {response.status_code}") # # # Simulate a regular user # regular_user = User(username='user1', role='user', is_authenticated=True) # request = factory.get('/posts/') # request.user = regular_user # view = PostViewSet.as_view({'get': 'list'}) # response = view(request) # print(f"User response status: {response.status_code}") # In a real Django setup, you would add PostViewSet to your urls.py: # from django.urls import path, include # from rest_framework.routers import DefaultRouter # # router = DefaultRouter() # router.register(r'posts', PostViewSet) # # urlpatterns = [ # path('api/', include(router.urls)), # ]
Debug
Known issues
breakingVersion 1.1.0 dropped support for older Python (3.6/3.7), Django (2.2.x/3.0.x), and Django REST Framework (3.10.x/3.11.x) versions. Ensure your environment meets the new requirements.
fix
Upgrade Python to 3.8+, Django to 3.1+, and DRF to 3.12+ (or compatible versions as per project's dependencies).
affects: >=1.1.0
breakingIn version 1.0.0, the `RoleFilterMixin`'s `role_filter_group` attribute was replaced by `role_filter_classes` (a list of `RoleFilter` instances).
fix
Update your `RoleFilterModelViewSet` (or any view using `RoleFilterMixin`) to use `role_filter_classes = [YourRoleFilter1, YourRoleFilter2]` instead of `role_filter_group = [...]`.
affects: >=1.0.0
gotchaThe `get_role_id` method on your `RoleFilterModelViewSet` is critical. It must return a string that matches the `role_id` defined in your `RoleFilter` subclasses. An incorrect or missing implementation will prevent the role-based filtering from activating correctly, potentially leading to unintended access or data exposure.
fix
Carefully implement `get_role_id(self, request)` to accurately map `request.user` to one of your defined `role_id` strings (e.g., 'admin', 'user'). Ensure all possible user states (e.g., authenticated, unauthenticated, different user types) are handled.
affects: All
gotchaEach `RoleFilter` subclass must explicitly define `get_allowed_actions`, `get_queryset`, and `get_serializer_class` (and optionally `get_serializer`) for its `role_id`. Failing to define these for a particular role might lead to default DRF behaviors (e.g., full queryset access) that bypass your intended role-based restrictions.
fix
Thoroughly review each `RoleFilter` class to ensure all necessary methods are implemented and return the expected restrictions or resources for that specific role. Be explicit to prevent accidental over-permissioning.
affects: All
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'rest_framework_role_filters'
The `djangorestframework-role-filters` library or its import path `rest_framework_role_filters` is not installed or not accessible in the Python environment.
fix
Ensure the package is correctly installed using pip: `pip install djangorestframework-role-filters` and that your virtual environment is active if you are using one.
AttributeError: 'RoleFilterModelViewSet' object has no attribute 'get_role_id'
When subclassing `RoleFilterModelViewSet`, the required `get_role_id` method was not implemented in the viewset, which is necessary for the role-based filtering logic to determine the current user's role.
fix
Implement the `get_role_id` method within your `RoleFilterModelViewSet` subclass to return the appropriate role identifier for the request.
KeyError: 'role_id' (or similar when accessing request.user.role.role_id)
This error typically occurs within the `get_role_id` method when it attempts to access a 'role' attribute or 'role_id' on `request.user` that does not exist, often because the user is anonymous or the user model/profile is not configured to have a 'role' attribute as expected by the role filter.
fix
Ensure that `request.user` is authenticated and that your user model or an associated profile has a 'role' attribute (or whatever attribute your `get_role_id` method expects) which provides a 'role_id'. You may need to adjust your `get_role_id` implementation to handle anonymous users or users without a defined role gracefully.
ImportError: cannot import name 'RoleFilter' from 'rest_framework_role_filters.role_filters'
There is a typo or an incorrect import path when trying to import the `RoleFilter` class. This can also happen if the installed version of the library has a different module structure than expected.
fix
Verify the exact import statement against the library's documentation. The correct import for `RoleFilter` is `from rest_framework_role_filters.role_filters import RoleFilter`.
Upgrade
Version history
1.1.0latest on PyPI · released Oct 6, 2023
Audit
Dependencies
DjangorequiredRequired for any Django project.
djangorestframeworkrequiredCore dependency for building REST APIs in Django.
Agent activity
17 hits · last 30 days
node
14
OpenAI (training)
2
Resources
djangorestframework-role-filters — pip install djangorestframework-role-filters · libregistry