django-wildewidgets Integration

LDAP ORM provides integration with django-wildewidgets through the LdapModelTableMixin, which enables the use of wildewidgets tables with LDAP ORM models.

Overview

The LdapModelTableMixin makes BasicModelTable work with ldaporm.models.Model by providing:

  • LDAP-aware search: Global search across multiple LDAP attributes

  • Query building: Proper construction of LDAP ORM query objects

  • Column filtering: Support for filtering on specific LDAP attributes

  • Integration: Seamless integration with wildewidgets table components

Basic Usage

To use the mixin, simply add LdapModelTableMixin before BasicModelTable in your table class inheritance list:

from wildewidgets import BasicModelTable
from ldaporm.wildewidgets import LdapModelTableMixin
from ldaporm import fields, models

# Define your LDAP ORM model
class LDAPUser(models.Model):

    EMPLOYEE_TYPE_CHOICES = [
        ('manager', 'Manager'),
        ('developer', 'Developer'),
        ('admin', 'Admin'),
    ]

    username = fields.CharField(max_length=50, primary_key=True)
    first_name = fields.CharField(max_length=50)
    last_name = fields.CharField(max_length=50)
    email = fields.EmailField()
    is_active = fields.BooleanField(default=True)
    employee_type = fields.CharField(max_length=50)

    class Meta:
        object_classes = ['top','person', 'organizationalPerson', 'inetOrgPerson']
        ...

# Create a table with the mixin
class LDAPUserTable(LdapModelTableMixin, BasicModelTable):
    model = LDAPUser
    page_length = 25
    striped = True
    fields: ClassVar[list[str]] = ['username', 'first_name', 'last_name', 'email', 'is_active', 'employee_type']
    verbose_names: ClassVar[dict[str, str]] = {
        'username': 'Username',
        'first_name': 'First Name',
        'last_name': 'Last Name',
        'email': 'Email',
        'is_active': 'Active',
    }
    hidden: ClassVar[list[str]] = ['employee_type']

    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        employee_type = DataTableFilter(
            header="Employee Type",
        )
        for choice in LDAPUser.EMPLOYEE_TYPE_CHOICES:
            employee_type.add_choice(choice[1], choice[0])
        self.add_filter("employee_type", employee_type)

    def get_initial_queryset(self) -> F:
        return cast("LdapManager", self.model.objects).order_by("username")

Configuration Options

See BasicModelTable for more information on the configuration options. The table will allow you to proceed normally as through you had a Django Model. The only difference is that you need to use the LdapModelTableMixin before BasicModelTable in your table class inheritance list.

Complete Example

Here’s a complete example showing all features:

from wildewidgets import BasicModelTable, Column
from ldaporm.wildewidgets import LdapModelTableMixin
from ldaporm import fields, models
from django.views.generic import ListView

# LDAP ORM Model
class Department(models.Model):
    name = fields.CharField(max_length=100)
    description = fields.CharField(max_length=500, blank=True)
    location = fields.CharField(max_length=100, blank=True)
    is_active = fields.BooleanField(default=True)

    class Meta:
        object_classes = ['organizationalUnit']
        ...

class User(models.Model):
    username = fields.CharField(max_length=50, primary_key=True)
    first_name = fields.CharField(max_length=50)
    last_name = fields.CharField(max_length=50)
    email = fields.EmailField()
    employee_id = fields.IntegerField(blank=True, null=True)
    department_dn = fields.CharField(max_length=500, blank=True)
    is_active = fields.BooleanField(default=True)
    created = fields.DateTimeField(auto_now_add=True)

    class Meta:
        object_classes = ['person', 'organizationalPerson', 'inetOrgPerson']
        ...

# Department Table
class DepartmentTable(LdapModelTableMixin, BasicModelTable):
    model = Department
    page_length = 25
    striped = True
    fields: ClassVar[list[str]] = ['name', 'description', 'location', 'is_active']
    verbose_names: ClassVar[dict[str, str]] = {
        'name': 'Name',
        'description': 'Description',
        'location': 'Location',
        'is_active': 'Active',
    }

    def get_initial_queryset(self) -> F:
        return cast("LdapManager", self.model.objects).order_by("name")

# User Table with Advanced Features
class UserTable(LdapModelTableMixin, BasicModelTable):
    model = User
    page_length = 25
    striped = True
    fields: ClassVar[list[str]] = ['username', 'first_name', 'last_name', 'email', 'is_active', 'employee_id']
    verbose_names: ClassVar[dict[str, str]] = {
        'username': 'Username',
        'first_name': 'First Name',
        'last_name': 'Last Name',
        'email': 'Email',
        'is_active': 'Active',
        'employee_id': 'Employee ID',
    }
    hidden: ClassVar[list[str]] = ['employee_id']

    def get_initial_queryset(self) -> F:
        return cast("LdapManager", self.model.objects).order_by("username")

Performance Considerations

  • Server-side filtering: The mixin leverages LDAP server-side filtering when possible

  • Query optimization: Use appropriate LDAP filters to minimize data transfer

  • Caching: Consider caching frequently accessed LDAP data

  • Pagination: Use wildewidgets pagination features for large datasets

  • Indexing: Ensure your LDAP server has appropriate indexes for searched attributes

Error Handling

The mixin handles common LDAP errors gracefully:

  • Connection errors: Displays appropriate error messages

  • Invalid queries: Validates query parameters before execution

  • Missing attributes: Handles cases where LDAP attributes are not present

  • Permission errors: Shows appropriate messages for access denied scenarios