Forms

This module provides form fields for using Tom Select in Django forms. These fields provide an enhanced selection interface with features like autocomplete, tagging, and remote data loading.

Model Choice Fields

TomSelectModelChoiceField

class django_tomselect.forms.TomSelectModelChoiceField(*args, queryset=None, config=None, **kwargs)[source]

Bases: BaseTomSelectModelMixin, ModelChoiceField

Wraps the TomSelectModelWidget as a form field.

Provides a form field for selecting a single model instance from options provided by a TomSelect autocomplete source. Leverages Django’s built-in ModelChoiceField validation with TomSelect UI enhancements.

Parameters:
field_base_class

alias of ModelChoiceField

widget_class

alias of TomSelectModelWidget

Example Usage

from django_tomselect.forms import TomSelectModelChoiceField
from django_tomselect.app_settings import TomSelectConfig

class AuthorForm(forms.Form):
    author = TomSelectModelChoiceField(
        config=TomSelectConfig(
            url='author-autocomplete',
            placeholder='Select an author...',
            minimum_query_length=2
        )
    )

TomSelectModelMultipleChoiceField

class django_tomselect.forms.TomSelectModelMultipleChoiceField(*args, queryset=None, config=None, **kwargs)[source]

Bases: BaseTomSelectModelMixin, ModelMultipleChoiceField

Wraps the TomSelectModelMultipleWidget as a form field.

Provides a form field for selecting multiple model instances from options provided by a TomSelect autocomplete source. Leverages Django’s built-in ModelMultipleChoiceField validation with TomSelect UI enhancements.

Parameters:
field_base_class

alias of ModelMultipleChoiceField

widget_class

alias of TomSelectModelMultipleWidget

Example Usage

class BookForm(forms.Form):
    authors = TomSelectModelMultipleChoiceField(
        config=TomSelectConfig(
            url='author-autocomplete',
            placeholder='Select authors...',
            plugin_remove_button=PluginRemoveButton()
        )
    )

Choice Fields

TomSelectChoiceField

class django_tomselect.forms.TomSelectChoiceField(*args, choices=None, config=None, **kwargs)[source]

Bases: BaseTomSelectMixin, ChoiceField

Single-select field for Tom Select.

Provides a form field for selecting a single value from options provided by a TomSelect autocomplete source. Validates that the selected value is among the allowed choices.

Parameters:
clean(value)[source]

Validate that the selected value is among the allowed choices.

Retrieves the autocomplete view and checks that the submitted value is in the set of allowed values.

Parameters:

value (Any) – The value to validate

Returns:

The validated value

Raises:

ValidationError – If the value is not among the allowed choices

Return type:

Any

widget_class

alias of TomSelectIterablesWidget

Example Usage

Assuming an autocomplete view is set up to return choices for the field, you can use TomSelectChoiceField like this:

class ColorForm(forms.Form):
    """Form demonstrating the use of TomSelectChoiceField with a color selection."""
    color = TomSelectChoiceField(
        config=TomSelectConfig(
            url='autocomplete-colors',
            value_field='value',
            label_field='label',
            placeholder='Select a color...',
        ),
        help_text="Select a color from the list"
    )

TomSelectMultipleChoiceField

class django_tomselect.forms.TomSelectMultipleChoiceField(*args, choices=None, config=None, **kwargs)[source]

Bases: BaseTomSelectMixin, MultipleChoiceField

Multi-select field for Tom Select.

Provides a form field for selecting multiple values from options provided by a TomSelect autocomplete source. Validates that all selected values are among the allowed choices.

Parameters:
clean(value)[source]

Validate that all selected values are allowed.

Retrieves the autocomplete view and checks that all submitted values are in the set of allowed values.

Parameters:

value (Any) – The value or values to validate

Returns:

The validated value list

Raises:

ValidationError – If any of the values are not among the allowed choices

Return type:

list[Any]

widget_class

alias of TomSelectIterablesMultipleWidget

Example Usage

Example usage for TomSelectMultipleChoiceField, assuming you have an autocomplete view set up to return choices:

class ProductForm(forms.Form):
    """Form demonstrating the use of TomSelectMultipleChoiceField for selecting product sizes."""
    available_sizes = TomSelectMultipleChoiceField(
        config=TomSelectConfig(
            url='autocomplete-sizes',
            placeholder='Select sizes...',
            value_field='value',
            label_field='label',
            placeholder='Select sizes...',
        ),
        help_text="Select one or more sizes for the product"
    )

Base Mixins

These mixins provide common functionality for TomSelect fields. They’re primarily for internal use but may be useful for custom field development.

BaseTomSelectMixin

class django_tomselect.forms.BaseTomSelectMixin(*args, choices=None, config=None, **kwargs)[source]

Bases: object

Mixin providing common initialization logic for TomSelect fields.

Extracts TomSelectConfig-related kwargs, sets up widget config and attrs. Handles merging of configuration from global defaults and instance-specific settings, managing widget attributes, and proper widget initialization.

Parameters:
__init__(*args, choices=None, config=None, **kwargs)[source]

Initialize a TomSelect field with optional configuration.

Parameters:
Return type:

None

BaseTomSelectModelMixin

class django_tomselect.forms.BaseTomSelectModelMixin(*args, queryset=None, config=None, **kwargs)[source]

Bases: object

Mixin providing common initialization logic for TomSelect model fields.

Similar to BaseTomSelectMixin but also handles queryset defaults and provides specialized validation for model-based selections. Manages configuration merging, widget attributes, and proper widget initialization with model querysets.

Parameters:
__init__(*args, queryset=None, config=None, **kwargs)[source]

Initialize a TomSelect model field with optional configuration.

Parameters:
Return type:

None

clean(value)[source]

Validate the selected value(s) against the queryset.

Updates the field’s queryset from the widget before performing validation to ensure that validation is performed against the most current data.

Parameters:

value (Any) – The value to validate

Returns:

The validated value

Raises:

ValidationError – If the value cannot be validated

Return type:

Any

Integration with Django Forms

All TomSelect fields can be used in Django forms just like standard form fields. They support all the usual field options like required, label, help_text, etc.

from django import forms
from django_tomselect.forms import TomSelectModelChoiceField
from django_tomselect.app_settings import TomSelectConfig

class MyForm(forms.Form):
    user = TomSelectModelChoiceField(
        config=TomSelectConfig(
            url='user-autocomplete',
            show_detail=True,
            show_update=True
        ),
        required=True,
        label='Select User',
        help_text='Search and select a user'
    )

The fields handle form validation, cleaning, and initial data automatically. They also properly integrate with Django’s form media system to include required JavaScript and CSS files.

Note

All TomSelect fields require a corresponding autocomplete view to handle the data loading. See the Views documentation for details on setting up autocomplete views.

TomSelectTokenField

A CharField that parses and validates a token-style query string, paired with TomSelectTokenWidget. The form value is one canonical token string like author:42 category:5 some free text.

from django_tomselect import TomSelectTokenField

class ArticleFilterForm(forms.Form):
    q = TomSelectTokenField(
        composite_view="autocomplete-article-token",  # URL name of CompositeAutocompleteView
        required=False,
        allow_free_text=True,
        max_query_length=4096,   # utf-8 byte cap
        max_tokens=32,
        max_values_per_operator=16,
    )

clean() enforces:

  • Parser-level errors (unknown operators, unterminated quotes, cap overflows)

    ValidationError. Unknown operators are NEVER silently re-routed as free text.

  • Operator.max_count / Operator.min_count >> field-level error.

  • allow_free_text=False >> un-prefixed input is rejected.

  • Empty operator values (e.g. author:) >> field-level error.

ORM coercion errors (category:tech against an id-based filter_lookup) are caught at apply-time, not in clean() - the field has no parent queryset. Surface them via form.add_error("q", e) in your view; see the Article Token-Style Search demo for the canonical pattern.

For cross-operator rules in Form.clean():

def clean(self):
    cleaned = super().clean()
    parsed = self.fields["q"].parse(cleaned.get("q", "") or "")
    if parsed.has("author") and not parsed.has("category"):
        raise ValidationError("If you specify author:, you must also specify category:.")
    return cleaned