Fields API Reference

Field Classes

class ldaporm.fields.Field(verbose_name: str | None = None, name: str | None = None, primary_key: bool = False, max_length: int | None = None, blank: bool = False, null: bool = False, default: ~typing.Any = <class 'django.db.models.NOT_PROVIDED'>, editable: bool = True, choices: list[typing.Any] | None = None, help_text: str = '', validators: ~collections.abc.Sequence[~collections.abc.Callable[[~typing.Any], None]] = (), error_messages: dict[str, str] | None = None, db_column: str | None = None)[source]

Bases: object

Base field class for LDAP ORM models.

This class provides enough of a Django ORM Field implementation to allow building Django ORM-like models and fool ModelForm into working with LDAP data. It handles the conversion between Python data types and LDAP attribute formats.

Parameters:
  • verbose_name – The human-readable name of the field.

  • name – The name of the field

  • primary_key – If True, this field is the primary key for the model.

  • max_length – The maximum length of the field.

  • blank – If True, the field is allowed to be blank in forms.

  • null – If True, the field is allowed to be empty in the LDAP server.

  • default – The default value for the field.

  • editable – If False, the field will not be editable in the admin.

  • choices – A list of choices for the field.

  • help_text – Help text for the field.

  • validators – A list of validators for the field.

  • error_messages – A dictionary of error messages for the field.

  • db_column – The attribute name in the LDAP schema.

__init__(verbose_name: str | None = None, name: str | None = None, primary_key: bool = False, max_length: int | None = None, blank: bool = False, null: bool = False, default: ~typing.Any = <class 'django.db.models.NOT_PROVIDED'>, editable: bool = True, choices: list[typing.Any] | None = None, help_text: str = '', validators: ~collections.abc.Sequence[~collections.abc.Callable[[~typing.Any], None]] = (), error_messages: dict[str, str] | None = None, db_column: str | None = None) None[source]
check(**_) list[django.core.checks.messages.Error | django.core.checks.messages.Warning][source]

Run field validation checks.

Returns:

A list of validation errors and warnings.

clean(value: Any, model_instance: Model) Any[source]

Convert the value’s type and run validation.

Validation errors from to_python() and validate() are propagated. Return the correct value if no error is raised.

Parameters:
  • value – The value to clean.

  • model_instance – The model instance being cleaned.

Returns:

The cleaned value.

Raises:

ValidationError – If validation fails.

contribute_to_class(cls, name: str) None[source]

Register the field with the model class it belongs to.

Parameters:
  • cls – The model class to register with.

  • name – The name of the field.

formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field instance for this field.

Parameters:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) list[str] | None[source]

Convert LDAP data to Python format.

Take data for one attribute from LDAP and convert it to our internal Python format. The value will always be a list of byte strings.

Subclasses should implement the actual logic for this, but first call super().from_db_value(value) to convert the byte strings in the list to unicode strings.

Parameters:

value – A list of byte strings from LDAP.

Returns:

A list of decoded strings or None if empty.

get_choices(include_blank: bool = True, blank_choice: list[tuple[str, str]] | None = None, limit_choices_to: Any = None)[source]

Get choices with a default blank choice included.

Parameters:
  • include_blank – Whether to include a blank choice.

  • blank_choice – The blank choice to include.

  • limit_choices_to – Unused parameter for compatibility.

Returns:

A list of choices for use in select widgets.

get_default() Any[source]

Get the default value for this field.

Returns:

The default value for the field.

has_default() bool[source]

Check if this field has a default value.

Returns:

True if the field has a default value, False otherwise.

limit_choices_to()[source]

Limit choices to a subset.

Raises:

NotImplementedError – This method is not implemented.

pre_save(model_instance: Model, add: bool) Any[source]

Get the field’s value just before saving.

Parameters:
  • model_instance – The model instance being saved.

  • add – Whether this is a new instance being added.

Returns:

The field’s value before saving.

run_validators(value: Any) None[source]

Run all validators on the given value.

Parameters:

value – The value to validate.

Raises:

ValidationError – If any validator fails.

save_form_data(obj: Model, value: Any) None[source]

Save form data to the model instance.

This is what django.forms.models.ModelForm calls to save data to our LdapModel instance.

Parameters:
  • obj – The model object to save data to.

  • value – The value to save.

set_attributes_from_name(name: str) None[source]

Set field attributes from the field name.

Parameters:

name – The name of the field.

to_db_value(value: Any) dict[str, list[bytes]][source]

Convert Python value to LDAP format.

Subclasses should implement this and do proper casting of the value from our internal data type to the appropriate value to stuff into LDAP, and then call super().to_db_value(value).

Parameters:

value – The Python value to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: Any) Any[source]

Convert the value to Python format.

Parameters:

value – The value to convert.

Returns:

The converted value.

validate(value: Any, model_instance: Model) None[source]

Validate the value and raise ValidationError if necessary.

Subclasses should override this to provide validation logic.

Parameters:
  • value – The value to validate.

  • model_instance – The model instance being validated.

Raises:

ValidationError – If validation fails.

value_from_object(obj: Model) Any[source]

Get the field’s value from a model object.

Parameters:

obj – The model object.

Returns:

The field’s value from the object.

value_to_string(obj: Model) str[source]

Convert the field’s value to a string.

Parameters:

obj – The model object.

Returns:

A string representation of the field’s value.

creation_counter: int = 0
default_error_messages: dict[str, str] = {'blank': 'This field cannot be blank.', 'invalid_choice': 'Value %(value)r is not a valid choice.', 'null': 'This field cannot be null.'}
default_validators: list[collections.abc.Callable[[Any], None]] = []
property description: str

Property that returns a description of the field type.

empty_strings_allowed: bool = True
empty_values: list[Any] = [None, '', [], (), {}]
property flatchoices: list[tuple[str, str]]

Property that returns flattened choices.

hidden: bool = False
property ldap_attribute: str

Get the LDAP attribute name for this field.

Returns:

The LDAP attribute name (db_column if set, otherwise field name).

many_to_many: Any = None
many_to_one: Any = None
one_to_many: Any = None
one_to_one: Any = None
related_model: Any = None
validators

Get all validators for this field.

class ldaporm.fields.CharField(*args, **kwargs)[source]

Bases: Field

A field for storing character strings.

This field handles string data with optional maximum length validation. It converts between Python strings and LDAP byte strings.

Keyword Arguments:

**kwargs – Keyword arguments passed to the parent class.

Parameters:

*args – Positional arguments passed to the parent class.

__init__(*args, **kwargs) None[source]
formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this character field.

Parameters:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) str | None[source]

Convert LDAP data to Python string.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The decoded string value or None if empty.

to_python(value: str | None) str | None[source]

Convert the value to a Python string.

Parameters:

value – The value to convert.

Returns:

The converted string value or None.

description: str = 'String (up to %(max_length)s)'
class ldaporm.fields.EmailField(*args, **kwargs)[source]

Bases: CharField

A field for storing email addresses.

This field extends CharField to add email validation. It uses Django’s built-in email validator and sets a default max_length of 254 to be compliant with RFCs 3696 and 5321.

Keyword Arguments:

**kwargs – Keyword arguments passed to the parent class.

Parameters:

*args – Positional arguments passed to the parent class.

__init__(*args, **kwargs)[source]
formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this email field.

Keyword Arguments:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

default_validators: list[collections.abc.Callable[[Any], None]] = [<django.core.validators.EmailValidator object>]
description: str = 'Email address'
class ldaporm.fields.BooleanField(*args, **kwargs)[source]

Bases: Field

A boolean field which stores data internally as bool() but stores the strings ‘true’ and ‘false’ in LDAP.

This field handles the conversion between Python boolean values and LDAP string representations, storing ‘true’ and ‘false’ in LDAP while working with Python bool values in the application.

Parameters:

*args – Positional arguments passed to the parent class.

Keyword Arguments:

**kwargs – Keyword arguments passed to the parent class.

__init__(*args, **kwargs) None[source]
formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this boolean field.

Parameters:
  • form_class – The form field class to use.

  • choices_form_class – Unused parameter for compatibility.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) bool | None[source]

Convert LDAP data to Python boolean.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The boolean value or None if empty.

Raises:

ValueError – If the LDAP data contains unexpected values.

to_db_value(value: bool | None) dict[str, list[bytes]][source]

Convert Python boolean to LDAP format.

Parameters:

value – The boolean value to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: None | bool | str) bool | None[source]

Convert the value to a Python boolean.

Parameters:

value – The value to convert. Can be None, bool, or string.

Returns:

The converted boolean value or None if null is allowed.

Raises:

ValidationError – If the value cannot be converted to a boolean.

LDAP_FALSE: str = 'false'
LDAP_TRUE: str = 'true'
default_error_messages: dict[str, str] = {'invalid': "'%(value)s' value must be either True or False.", 'invalid_nullable': "'%(value)s' value must be either True, False, or None."}
description: str = 'Boolean (Either True or False)'
empty_strings_allowed: bool = False
class ldaporm.fields.AllCapsBooleanField(*args, **kwargs)[source]

Bases: BooleanField

A boolean field that uses uppercase ‘TRUE’ and ‘FALSE’ in LDAP.

This field is similar to BooleanField but uses uppercase strings for LDAP storage, which is common in some LDAP schemas.

LDAP_FALSE: str = 'FALSE'
LDAP_TRUE: str = 'TRUE'
class ldaporm.fields.IntegerField(verbose_name: str | None = None, name: str | None = None, primary_key: bool = False, max_length: int | None = None, blank: bool = False, null: bool = False, default: ~typing.Any = <class 'django.db.models.NOT_PROVIDED'>, editable: bool = True, choices: list[typing.Any] | None = None, help_text: str = '', validators: ~collections.abc.Sequence[~collections.abc.Callable[[~typing.Any], None]] = (), error_messages: dict[str, str] | None = None, db_column: str | None = None)[source]

Bases: Field

A field for storing integer values.

This field handles integer data, converting between Python integers and LDAP string representations.

check(**kwargs) list[django.core.checks.messages.Error | django.core.checks.messages.Warning][source]

Run field validation checks.

Returns:

A list of validation errors and warnings.

formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this integer field.

Keyword Arguments:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) int | None[source]

Convert LDAP data to Python integer.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The parsed integer value or None if empty.

to_db_value(value: int | None) dict[str, list[bytes]][source]

Convert Python integer to LDAP format.

Parameters:

value – The integer value to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: str) int[source]

Convert the value to a Python integer.

Parameters:

value – The value to convert.

Returns:

The converted integer value.

Raises:

ValidationError – If the value cannot be converted to an integer.

default_error_messages: dict[str, str] = {'invalid': "'%(value)s' value must be an integer."}
description: str = 'Integer'
empty_strings_allowed: bool = False
class ldaporm.fields.DateTimeField(verbose_name: str | None = None, name: str | None = None, auto_now: bool = False, auto_now_add: bool = False, **kwargs: Any)[source]

Bases: DateField

A field for storing dates with time information.

This field handles datetime data, converting between Python datetime objects and LDAP datetime string formats. It supports multiple LDAP datetime formats and handles timezone conversion.

formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this datetime field.

Parameters:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) datetime | None[source]

Convert LDAP data to Python datetime.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The parsed datetime value or None if empty.

Raises:

ValidationError – If the LDAP datetime format is not supported.

pre_save(model_instance: Model, add: bool) Any[source]

Get the field’s value just before saving.

Parameters:
  • model_instance – The model instance being saved.

  • add – Whether this is a new instance being added.

Returns:

The field’s value before saving.

to_db_value(value: datetime | date | None) dict[str, list[bytes]][source]

Convert Python datetime to LDAP format.

Parameters:

value – The datetime value to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: str | datetime | date | None) datetime | None[source]

Convert the value to a Python datetime.

Parameters:

value – The value to convert. Can be string, datetime, date, or None.

Returns:

The converted datetime value or None.

Raises:

ValidationError – If the value cannot be converted to a datetime.

LDAP_DATETIME_FORMAT: str = '%Y%m%d%H%M%S+0000'
LDAP_DATETIME_FORMATS: list[str] = ['%Y%m%d%H%M%SZ', '%Y%m%d%H%M%S+0000']
default_error_messages: dict[str, str] = {'invalid': "'%(value)s' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format.", 'invalid_date': "'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid date.", 'invalid_datetime': "'%(value)s' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) but it is an invalid date/time.", 'invalid_ldap_datetime': "LDAP datetime '%(value)s' value is not in a supported format"}
description: str = 'Date (with time)'
empty_strings_allowed: bool = False
class ldaporm.fields.DateField(verbose_name: str | None = None, name: str | None = None, auto_now: bool = False, auto_now_add: bool = False, **kwargs: Any)[source]

Bases: Field

A field for storing dates without time information.

This field handles date data, converting between Python date objects and LDAP date string format (YYYYMMDD).

Keyword Arguments:
  • verbose_name – The human-readable name of the field.

  • name – The name of the field in the LDAP schema.

  • auto_now – If True, automatically set to current date on save.

  • auto_now_add – If True, automatically set to current date on creation.

  • **kwargs – Additional keyword arguments passed to the parent class.

__init__(verbose_name: str | None = None, name: str | None = None, auto_now: bool = False, auto_now_add: bool = False, **kwargs: Any) None[source]
check(**kwargs) list[django.core.checks.messages.Error | django.core.checks.messages.Warning][source]

Run field validation checks.

Returns:

A list of validation errors and warnings.

contribute_to_class(cls, name: str, **kwargs) None[source]

Register the field with the model class and add convenience methods.

Parameters:
  • cls – The model class to register with.

  • name – The name of the field.

  • **kwargs – Additional keyword arguments.

formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this date field.

Parameters:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) date | None[source]

Convert LDAP data to Python date.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The parsed date value or None if empty.

pre_save(model_instance: Model, add: bool) date | None[source]

Get the field’s value just before saving.

Parameters:
  • model_instance – The model instance being saved.

  • add – Whether this is a new instance being added.

Returns:

The field’s value before saving.

to_db_value(value: date | datetime | None) dict[str, list[bytes]][source]

Convert Python date to LDAP format.

Parameters:

value – The date value to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: str | date | datetime | None) date | None[source]

Convert the value to a Python date.

Parameters:

value – The value to convert.

Returns:

The converted date value or None.

Raises:

ValidationError – If the value cannot be converted to a date.

value_to_string(obj: Model) str[source]

Convert the field’s value to a string.

Parameters:

obj – The model object.

Returns:

An ISO format string representation of the date.

LDAP_DATETIME_FORMAT: str = '%Y%m%d'
default_error_messages: dict[str, str] = {'invalid': "'%(value)s' value has an invalid date format. It must be in YYYY-MM-DD format.", 'invalid_date': "'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid date."}
description: str = 'Date (without time)'
empty_strings_allowed: bool = False
class ldaporm.fields.BinaryField(verbose_name: str | None = None, name: str | None = None, primary_key: bool = False, max_length: int | None = None, blank: bool = False, null: bool = False, default: ~typing.Any = <class 'django.db.models.NOT_PROVIDED'>, editable: bool = True, choices: list[typing.Any] | None = None, help_text: str = '', validators: ~collections.abc.Sequence[~collections.abc.Callable[[~typing.Any], None]] = (), error_messages: dict[str, str] | None = None, db_column: str | None = None)[source]

Bases: Field

A field for storing binary data.

This field handles binary data, converting between Python bytes objects and LDAP binary attributes. It’s commonly used for storing photos, certificates, and other binary data in LDAP.

Keyword Arguments:

**kwargs – Keyword arguments passed to the parent class.

Parameters:

*args – Positional arguments passed to the parent class.

check(**kwargs) list[django.core.checks.messages.Error | django.core.checks.messages.Warning][source]

Run field validation checks.

Returns:

A list of validation errors and warnings.

formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this binary field.

Parameters:
  • form_class – The form field class to use.

  • choices_form_class – The form field class to use for choices.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value: list[bytes]) bytes | None[source]

Convert LDAP data to Python bytes.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The binary data as bytes or None if empty.

to_db_value(value: bytes | bytearray | None) dict[str, list[bytes]][source]

Convert Python bytes to LDAP format.

Parameters:

value – The binary data to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: bytes | bytearray | None) bytes | None[source]

Convert the value to Python bytes.

Parameters:

value – The value to convert. Can be bytes, bytearray, or None.

Returns:

The converted bytes value or None.

Raises:

ValidationError – If the value cannot be converted to bytes.

default_error_messages: dict[str, str] = {'invalid': "'%(value)s' value must be bytes or bytearray."}
description: str = 'Binary data'
empty_strings_allowed: bool = False
class ldaporm.fields.CharListField(*args, **kwargs)[source]

Bases: CharField

A field for storing lists of character strings.

This field handles lists of strings, converting between Python lists and LDAP multi-valued attributes. It treats newlines as delimiters when converting from strings to lists.

Keyword Arguments:

**kwargs – Keyword arguments passed to the parent class.

Parameters:

*args – Positional arguments passed to the parent class.

__init__(*args, **kwargs) None[source]
formfield(form_class: type[django.forms.Field] | None = None, choices_form_class: type[django.forms.Field] | None = None, **kwargs) Field[source]

Return a Django form field for this character list field.

Keyword Arguments:
  • form_class – Unused parameter for compatibility.

  • choices_form_class – Unused parameter for compatibility.

  • **kwargs – Additional keyword arguments for the form field.

Returns:

A Django form field instance.

from_db_value(value)[source]

Convert LDAP data to Python list.

This is important because we don’t want CharField.from_db_value() to execute; we only want Field.from_db_value(). CharField.from_db_value() turns the list that Field.from_db_value() returns into a string. We actually want the list.

Parameters:

value – A list of byte strings from LDAP.

Returns:

A list of decoded strings.

get_default() list[str][source]

Get the default value for this field.

Returns:

An empty list if no default is set, otherwise the default value.

to_python(value: str | list[str] | None) list[str][source]

Convert the value to a Python list of strings.

Keyword Arguments:

value – The value to convert. Can be string, list, or None.

Returns:

A list of strings. If value is a string, it’s split on newlines.

description: str = 'List of strings (each up to %(max_length)s)'
class ldaporm.fields.ActiveDirectoryTimestampField(verbose_name: str | None = None, name: str | None = None, auto_now: bool = False, auto_now_add: bool = False, **kwargs: Any)[source]

Bases: DateTimeField

A field for storing Active Directory timestamp values as datetime objects.

This field handles Active Directory timestamps, which are stored as 18-digit integers representing the number of 100-nanosecond intervals since January 1, 1601 UTC (also known as Windows NT time format). It converts between these timestamps and Python datetime objects.

The Active Directory timestamp is the number of 100-nanosecond intervals (1 nanosecond = one billionth of a second) since Jan 1, 1601 UTC.

from_db_value(value: list[bytes]) datetime | None[source]

Convert LDAP data to Python datetime.

Parameters:

value – A list of byte strings from LDAP.

Returns:

The parsed datetime value or None if empty.

Raises:

ValidationError – If the LDAP timestamp format is invalid.

to_db_value(value: datetime | date | None) dict[str, list[bytes]][source]

Convert Python datetime to Active Directory timestamp format.

Parameters:

value – The datetime value to convert.

Returns:

A dictionary mapping LDAP attribute name to list of bytes.

to_python(value: str | datetime | date | None) datetime | None[source]

Convert the value to a Python datetime.

Parameters:

value – The value to convert. Can be string, integer, datetime, or None.

Returns:

The converted datetime value or None.

Raises:

ValidationError – If the value cannot be converted to a datetime.

AD_EPOCH: datetime = datetime.datetime(1601, 1, 1, 0, 0, tzinfo=<UTC>)
INTERVALS_PER_DAY: int = 864000000000
INTERVALS_PER_SECOND: int = 10000000
default_error_messages: dict[str, str] = {'invalid': "'%(value)s' value has an invalid format. It must be an 18-digit integer.", 'invalid_timestamp': "'%(value)s' value is not a valid Active Directory timestamp.", 'timestamp_out_of_range': "'%(value)s' value represents a timestamp outside the supported range."}
description: str = 'Active Directory DateTime'