Django REST Framework: ViewSets
For list endpoints, LDAP ORM provides integration with Django REST Framework (DRF) through specialized viewsets that work with LDAP ORM models and fields.
URL Configuration
Django URLs
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSet, DepartmentViewSet
router = DefaultRouter()
router.register(r'users', UserViewSet, basename='user')
router.register(r'departments', DepartmentViewSet, basename='department')
urlpatterns = [
path('api/', include(router.urls)),
]
ViewSet Example
You can just use the ModelViewSet class from DRF, and it will work with
LDAP ORM models and fields:
LDAPCursorPaginationis a pagination class that uses the.page()method to get paged results.LdapOrderingFilteris a filter class that allows you to order the results by a given attribute.LdapFilterBackendis an abstract base class for creating custom filter backends that work with LDAP ORM models.
from typing import cast
from ldaporm.managers import LdapManager
from ldaporm.restframework import HyperlinkedModelSerializer, LdapCursorPagination, LdapOrderingFilter, LdapFilterBackend
from rest_framework import viewsets
from .mycode.ldap.models import LDAPUser
class UserFilterBackend(LdapFilterBackend):
"""
Custom filter backend for LDAPUser using the abstracted LdapFilterBackend.
"""
filter_fields = {
'uid': {'lookup': 'iexact', 'type': 'string'},
'mail': {'lookup': 'icontains', 'type': 'string'},
'employee_number': {'lookup': 'iexact', 'type': 'integer'},
'employee_type': {'lookup': 'iexact', 'type': 'string'},
'full_name': {'lookup': 'icontains', 'type': 'string'},
'gid_number': {'lookup': 'iexact', 'type': 'integer'},
'uid_number': {'lookup': 'iexact', 'type': 'integer'},
'login_shell': {'lookup': 'iexact', 'type': 'string'},
}
class UserViewSet(viewsets.ModelViewSet):
model = LDAPUser
serializer_class = UserSerializer
pagination_class = LdapCursorPagination
lookup_field = 'uid'
filter_backends = [UserFilterBackend, LdapOrderingFilter]
ordering_fields = ['uid', 'full_name']
ordering = ('uid', )
def get_queryset(self):
return cast("LdapManager", LDAPUser.objects).all()
Filter Backend Configuration
The LdapFilterBackend provides a configuration-driven approach to filtering
LDAP ORM models. You define filterable fields and their behavior in a
filter_fields dictionary.
Field Configuration
Each field in the filter_fields dictionary can be configured with:
lookup: The LDAP ORM lookup type (e.g., ‘iexact’, ‘icontains’, ‘exact’)
type: The field type for value conversion (‘string’, ‘integer’, ‘boolean’, ‘float’)
class DepartmentFilterBackend(LdapFilterBackend):
filter_fields = {
'name': {'lookup': 'icontains', 'type': 'string'},
'code': {'lookup': 'iexact', 'type': 'string'},
'budget': {'lookup': 'gte', 'type': 'integer'},
'active': {'lookup': 'exact', 'type': 'boolean'},
}
Supported Lookup Types
iexact: Case-insensitive exact match
icontains: Case-insensitive contains
exact: Exact match
contains: Contains
startswith: Starts with
endswith: Ends with
gte: Greater than or equal
lte: Less than or equal
gt: Greater than
lt: Less than
Supported Field Types
string: String values (no conversion)
integer: Integer values (converts string to int)
boolean: Boolean values (converts string to bool)
float: Float values (converts string to float)
API Usage Examples
With the above filter backend, you can make API calls like:
# Filter by user ID (exact match)
GET /api/users/?uid=john.doe
# Filter by email (contains)
GET /api/users/?mail=example.com
# Filter by employee type (exact match)
GET /api/users/?employee_type=staff
# Filter by full name (contains)
GET /api/users/?full_name=John
# Filter by employee number (exact match)
GET /api/users/?employee_number=12345
# Combine filtering with ordering
GET /api/users/?employee_type=staff&ordering=uid
# Multiple filters
GET /api/users/?employee_type=staff&gid_number=1000&ordering=-full_name
Advanced Filter Backend
For more complex filtering logic, you can override the get_filter_queryset method:
class AdvancedUserFilterBackend(LdapFilterBackend):
filter_fields = {
'uid': {'lookup': 'iexact', 'type': 'string'},
'mail': {'lookup': 'icontains', 'type': 'string'},
}
def get_filter_queryset(self, request, queryset, view):
"""
Apply custom filtering logic beyond the standard filter_fields.
"""
# Apply standard filters first
queryset = self.apply_filters(request, queryset)
# Add custom filtering logic
department = request.query_params.get('department')
if department:
queryset = queryset.filter(department__icontains=department)
return queryset
OpenAPI Documentation
The LdapFilterBackend automatically generates OpenAPI schema parameters
for documentation. The filter fields are automatically included in the API
documentation with appropriate descriptions and types.
Example Response
When using the filter backend, API responses maintain the standard DRF format:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"uid": "john.doe",
"full_name": "John Doe",
"mail": ["john.doe@example.com"],
"employee_number": 12345,
"employee_type": "staff"
},
{
"uid": "jane.smith",
"full_name": "Jane Smith",
"mail": ["jane.smith@example.com"],
"employee_number": 12346,
"employee_type": "staff"
}
]
}